"helps" sometimes) → using someone's (undocumented) API without looking at the implementation? → using an undocumented API you wrote in the past, without looking at the implementation? 9 — @basthomas
removing the duplicates in the parts that are not overlap completely (in the meaning that we care only if the last x values of 1st array overlaps with the same x values of the 2nd, but we don't care if some duplicates are randomly exist in the body of array) 16 — @basthomas
string collected till /// this moment /// - Parameter array2: an array that contain new elements that should be /// added in array1 init(array1: [String], array2: [String]) { self.array1 = array1 self.array2 = array2 } /// Combines two arrays with partial removal of duplicates /// /// - Returns: An array of complate `array1` and partially (removing the first /// occurances in both arrays) added `array2` func combineOutputs() -> [String] { return concatArrays() } 18 — @basthomas
/// Adds two arrays with removing the overlap between them /// /// - Parameter existing: the exsting elemets. /// - Parameter newEntries: the elements that should be added to the front /// - Returns: the sum of both array with `newEntries` at the front static func concatenateWithoutOverlap( existing: [String], newEntries: [String] ) throws -> [String] { let occourences = newEntries.enumerated().filter { index, entry in newEntries[index] == existing.first } let _overlapStart = occourences.first(where: { index in existing.starts(with: newEntries[index..<-1]) }) guard let overlapStart = _overlapStart else { throw ListError.noOverlap } return [Array(arr3.prefix(through: 1)), arr2].flatMap { $0 } } } 20 — @basthomas
/// Adds two arrays with removing the overlap between them /// /// - Parameter existing: the exsting elemets. /// - Parameter newEntries: the elements that should be added to the front /// - Returns: the sum of both array with `newEntries` at the front static func concatenateWithoutOverlap( existing: [String], newEntries: [String] ) throws -> [String] { // implementation } } 22 — @basthomas
/// Prepends an array to front of an existing one, /// without adding the overlap twice. /// /// Example: /// /// ```swift /// let existing = [4, 3, 2, 1] /// let newEntries = [6, 5, 4, 3] /// Lists.concatenateWithoutOverlap( /// existing: existing, /// newEntries: newEntries /// ) // Returns [6, 5, 4, 3, 2, 1] /// ``` /// /// - Parameter existing: the existing array. /// - Parameter newEntries: the array that should be added to the front /// - Returns: returns the new array static func stitch( existing: [String], with newEntries: [String] ) throws -> [String] { // Get the index of all occurrences of the first element from the // `newEntries` array in `existing` let occurrences = newEntries.enumerated().filter { index, entry in newEntries[index] == existing.first } // Check if one of the slices of `existing` is prefix of // the `newEntries` array let _overlapStart = occurrences.first(where: { index in existing.starts(with: newEntries[index..<-1]) }) guard let overlapStart = _overlapStart else { throw ListError.noOverlap } // Add the `newEntries` without the overlap at the end of the existing array return [Array(arr3.prefix(through: 1)), arr2].flatMap { $0 } } } 24 — @basthomas
/// - Parameter color: the text color to use. Available colors are a subset /// of `XINGColor` and are safe to use for text. /// - Parameter weight: the text weight to use. This will be used for the text's font. /// - Parameter size: the text size to use. This will be used for the text's font. /// - Parameter numberOfLines: The number of lines of text to render. /// To remove any maximum limit, and use as many lines as needed, /// set the value of this property to 0. @objc public init( color: TextColor, weight: TextWeight, size: TextSize, numberOfLines: Int ) { self._color = color self.weight = weight self.size = size self.numberOfLines = numberOfLines } 44 — @basthomas
configuration from. /// /// - Returns: a `TextConfiguration` based on the label, if it uses valid /// text configuration values. If not, it will assert and revert to default options. @objc public static func from(label: UILabel) -> TextConfiguration { func textColor(from color: UIColor) -> TextColor { guard let _textColor = TextColor.all.first(where: { $0.uiColor == label.textColor }) else { assertionFailure("Could not convert label's color to a valid TextColor. This will default to `.grey800` in production, which may be unexpected.") return .grey800 } return _textColor } func textWeight(from font: UIFont) -> TextWeight { guard let _textStyle = TextWeight.from(font: font) else { assertionFailure("Could not convert font's weight to a valid TextWeight. This will default to `.regular` in production, which may be unexpected.") return .regular } return _textStyle } func textSize(from font: UIFont) -> TextSize { guard let _textSize = TextSize.from(font: font) else { assertionFailure("Could not convert font's size to a valid TextSize. This will default to `.default12` in production, which may be unexpected.") return .default12 } return _textSize } return .init( color: textColor(from: label.textColor), weight: textWeight(from: label.font), size: textSize(from: label.font), numberOfLines: label.numberOfLines ) } 46 — @basthomas
/// - Parameter label: the `UILabel` instance to apply the /// text configuration to. /// /// - Returns: a reference to the label that has the configuration /// aplied to it. @discardableResult @objc public func apply(to label: UILabel) -> UILabel { label.textColor = color label.font = font label.numberOfLines = numberOfLines return label } 49 — @basthomas
fixed / covered during development) → Objective-C interop → Chainable API → It's not perfect (and that is OK) → Architecture design is missing 51 — @basthomas
Don't be afraid to use types → The compiler is your enemy → We should explain the architectural design → Prevent "rest of the damn owl" syndrom → Use assertions! 52 — @basthomas
write the correct code. There is no correct code. There is no silver bullet. → I want to help the most correct code to be written. → I want to prevent incorrect code to be written. → I want to fail early and often. → (but for that, I need it to be testable) → Iterate, iterate, iterate 53 — @basthomas
together and bounce off ideas → Documentation is helpful for yourself when writing code, too → Documentation helps you with naming, scope, testability and readability → Having testable code feels awesome → Snapshot tests are the root of all evil 54 — @basthomas
Conal Elliot https://github.com/conal/talk-2014-lambdajam-denotational-design "... But That Should Work?" by me https://basthomas.github.io/but-that-should-work Point-Free by Brandon Williams & Stephen Celis https://www.pointfree.co 56 — @basthomas