UnderstandingYourToddler.pdf

 UnderstandingYourToddler.pdf

Often we can go back and look at someone's toddler years and see signs of the person they would become. In this talk we look at the proposals for Swift 3 and imagine the language Swift will become.

5af07e950f10c7c1df1c44bed055c1eb?s=128

dimsumthinking

May 27, 2016
Tweet

Transcript

  1. None
  2. None
  3. ?

  4. None
  5. None
  6. None
  7. Understanding Your Toddler iOSConf 2016 Daniel H Steinberg @dimsumthinking

  8. Understanding Your Toddler iOSConf 2016 Daniel H Steinberg @dimsumthinking

  9. Understanding Your Toddler iOSConf 2016 Daniel H Steinberg @dimsumthinking No,

    this is not the same talk I gave last week at UIKonf
  10. Summer 2010

  11. None
  12. None
  13. Summer 2010

  14. Xcode 4 shipped

  15. Xcode IB

  16. None
  17. 18 months

  18. None
  19. Xcode 4.2

  20. LLVM Only

  21. iOS 5

  22. ARC

  23. WWDC 2014

  24. None
  25. Swift 1.0

  26. Swift 1.1

  27. Swift 1.2

  28. WWDC 2015

  29. "Swift will be open sourced by the end of this

    year"
  30. December 3, 2015

  31. None
  32. None
  33. Proposals from the Community

  34. PRs from the Community

  35. Committers

  36. Conversation

  37. Swift Evolution

  38. Open

  39. Swift 3

  40. "We have had a focus on getting to source stability"

  41. Swift 3 focus on source stability

  42. API design guidelines Focus and refine the language Adoption of

    naming guidelines in key APIs Automatic application of naming guidelines to imported Objective-C APIs Swiftification of imported Objective-C APIs Improvements to tooling quality
  43. API design guidelines Focus and refine the language Adoption of

    naming guidelines in key APIs Automatic application of naming guidelines to imported Objective-C APIs Swiftification of imported Objective-C APIs Improvements to tooling quality
  44. API design guidelines Focus and refine the language Adoption of

    naming guidelines in key APIs Automatic application of naming guidelines to imported Objective-C APIs Swiftification of imported Objective-C APIs Improvements to tooling quality
  45. API design guidelines Focus and refine the language Adoption of

    naming guidelines in key APIs Automatic application of naming guidelines to imported Objective-C APIs Swiftification of imported Objective-C APIs Improvements to tooling quality
  46. API design guidelines Focus and refine the language Adoption of

    naming guidelines in key APIs Automatic application of naming guidelines to imported Objective-C APIs Swiftification of imported Objective-C APIs Improvements to tooling quality
  47. API design guidelines Focus and refine the language Adoption of

    naming guidelines in key APIs Automatic application of naming guidelines to imported Objective-C APIs Swiftification of imported Objective-C APIs Improvements to tooling quality
  48. Swift 3 focus on source stability

  49. A Few Previews of Coming Attractions

  50. 0025 - Scoped Access Levels

  51. public internal private

  52. public internal private

  53. public internal private

  54. public internal private

  55. public internal fileprivate

  56. public internal fileprivate private

  57. class MyClass { private var myProperty = "Hello" private func

    myPrivateMethod() { print(myProperty) } fileprivate func myFilePrivateMethod(numberOfTimes times: Int) { for _ in 1 ... times { myPrivateMethod() } } } extension MyClass { func myExtensionMethod(numberOfTimes times: Int) { myFilePrivateMethod(numberOfTimes: times) } }
  58. class MyClass { private var myProperty = "Hello" private func

    myPrivateMethod() { print(myProperty) } fileprivate func myFilePrivateMethod(numberOfTimes times: Int) { for _ in 1 ... times { myPrivateMethod() } } } extension MyClass { func myExtensionMethod(numberOfTimes times: Int) { myFilePrivateMethod(numberOfTimes: times) } }
  59. class MyClass { private var myProperty = "Hello" private func

    myPrivateMethod() { print(myProperty) } fileprivate func myFilePrivateMethod(numberOfTimes times: Int) { for _ in 1 ... times { myPrivateMethod() } } } extension MyClass { func myExtensionMethod(numberOfTimes times: Int) { myFilePrivateMethod(numberOfTimes: times) } }
  60. class MyClass { private var myProperty = "Hello" private func

    myPrivateMethod() { print(myProperty) } fileprivate func myFilePrivateMethod(numberOfTimes times: Int) { for _ in 1 ... times { myPrivateMethod() } } } extension MyClass { func myExtensionMethod(numberOfTimes times: Int) { myFilePrivateMethod(numberOfTimes: times) } }
  61. class MyClass { private var myProperty = "Hello" private func

    myPrivateMethod() { print(myProperty) } fileprivate func myFilePrivateMethod(numberOfTimes times: Int) { for _ in 1 ... times { myPrivateMethod() } } } extension MyClass { func myExtensionMethod(numberOfTimes times: Int) { myFilePrivateMethod(numberOfTimes: times) } }
  62. public internal fileprivate private

  63. 0004 - Remove ++ and —

  64. while count < upperLimit { print( myArray[count++]) }

  65. while count < upperLimit { print( myArray[count++]) }

  66. while count < upperLimit { print( myArray[count]) count += 1

    }
  67. 0007 - Remove C Style for loops with conditions and

    incrementors
  68. for (int i = 0; i < array.count; i++)

  69. for (int i = 0; i < array.count; i++)

  70. 0053 - Remove explicit use of let from Function Parameters

  71. func double(input: Int) -> Int { // ... }

  72. func double(let input: Int) -> Int { // ... }

  73. func double(let input: Int) -> Int { // ... }

  74. 0003 - Remove var from Function Parameters

  75. func double(input: Int) -> Int { input = input *

    2 return input }
  76. func double(var input: Int) -> Int { input = input

    * 2 return input }
  77. func double(var input: Int) -> Int { input = input

    * 2 return input }
  78. func double(input: Int) -> Int { var localInput = input

    localInput = localInput * 2 return localInput }
  79. func double(input: Int) -> Int { var localInput = input

    localInput = localInput * 2 return localInput }
  80. func double(input: Int) -> Int { var input = input

    input = input * 2 return input } Name Shadowing
  81. func double(input: Int) -> Int { var input = input

    input = input * 2 return input }
  82. 0031 - Adjusting inout Declarations for Type Decoration

  83. func double(input: Int) { input = input * 2 }

  84. func double(inout input: Int) { input = input * 2

    }
  85. func double(inout input: Int) { input = input * 2

    }
  86. func double(input: inout Int) { input = input * 2

    }
  87. 0053 - Limiting inout capture to @noescape context

  88. func escape(f: () -> ()) {} func example(inout x: Int)

    { escape { _ = x } }
  89. func escape(f: () -> ()) {} func example(inout x: Int)

    { escape { _ = x } }
  90. func escape(f: () -> ()) {} func example(inout x: Int)

    { escape { _ = x } }
  91. func escape(f: () -> ()) {} func example(inout x: Int)

    { escape { _ = x } }
  92. func escape(f: () -> ()) {} func example(inout x: Int)

    { escape { _ = x } }
  93. func escape(f: () -> ()) {} func example(inout x: Int)

    { escape { _ = x } }
  94. func escape(f: () -> ()) {} func example(inout x: Int)

    { escape { _ = x } }
  95. func noEscape(@noescape f: () -> ()) {} func example(inout x:

    Int) { noEscape { _ = x } }
  96. func noEscape(@noescape f: () -> ()) {} func example(inout x:

    Int) { noEscape { _ = x } } safe because @noescape => closure can't be called after function returns
  97. func escape(f: () -> ()) {} func example(inout x: Int)

    { escape { _ = x } }
  98. func escape(f: () -> ()) {} func example(inout x: Int)

    { escape {[x] in _ = x } }
  99. func escape(f: () -> ()) {} func example(inout x: Int)

    { escape {[x] in _ = x } } [x] is a capture list a constant is initialized to have the value of x
  100. 0049 - Move @noescape and @autoclosure to be type attributes

  101. func noEscape(@noescape f: () -> ()) {}

  102. func noEscape(f: @noescape () -> ()) {}

  103. func noEscape(f: @autoclosure () -> ()) {}

  104. 0002 - Remove currying func declaration syntax

  105. 0002 - Remove currying func declaration syntax

  106. 0002 - Remove currying func declaration syntax

  107. func curried(x: Int)(y: Int) -> Int { return {(y: Int)

    -> Int in return x * y } } curried(7)(8)
  108. func curried(x: Int)(y: Int) -> Int { return {(y: Int)

    -> Int in return x * y } } curried(7)(8)
  109. func curried(x: Int)(y: Int) -> Int { return {(y: Int)

    -> Int in return x * y } } curried(7)(8)
  110. func curried(x: Int)(y: Int) -> Int { return {(y: Int)

    -> Int in return x * y } } curried(7)(8)
  111. func curried(x: Int)(y: Int) -> Int { return {(y: Int)

    -> Int in return x * y } } curried(7)(8) 7 * y
  112. func curried(x: Int)(y: Int) -> Int { return {(y: Int)

    -> Int in return x * y } } curried(7)(8) 7 * 8
  113. func curried(x: Int)(y: Int) -> Int { return {(y: Int)

    -> Int in return x * y } } curried(7)(8)
  114. func curried(x: Int)(y: Int) -> Int { return {(y: Int)

    -> Int in return x * y } } curried(7)(8)
  115. func curried(x: Int)(y: Int) -> Int { return {(y: Int)

    -> Int in return x * y } } curried(7)(8)
  116. func curried(x: Int) -> (y: Int) -> Int { return

    {(y: Int) -> Int in return x * y } } curried(7)(8)
  117. func curried(x: Int) -> (y: Int) -> Int { return

    {(y: Int) -> Int in return x * y } } curried(7)(8)
  118. func curried(x: Int) -> (y: Int) -> Int { return

    {(y: Int) -> Int in return x * y } } curried(7)(8)
  119. func curried(x: Int) -> (y: Int) -> Int { return

    {(y: Int) -> Int in return x * y } } curried(7)(8)
  120. func curried(x: Int) -> (y: Int) -> Int { return

    {(y: Int) -> Int in return x * y } } curried(7)(8)
  121. Testing

  122. Playgrounds

  123. Package Manager

  124. Objective-C

  125. 0022 - Referencing the Obj-C selector of a method

  126. class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func

    setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: "callbackMethod", name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
  127. class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func

    setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: "callbackMethod", name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
  128. class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func

    setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: "callbackMethod", name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
  129. class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func

    setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: "callbackMethod", name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
  130. class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func

    setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: "callbackMethod", name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
  131. class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func

    setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: "callbackMethod", name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
  132. class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func

    setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: #selector(callbackMethod), name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
  133. class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func

    setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: #selector(MyClass.callbackMethod), name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
  134. class MyClass : NSObject { func callbackMethod(){} func callbackMethod(with notification:

    NSNotification){} func setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: #selector(MyClass.callbackMethod), name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
  135. class MyClass : NSObject { func callbackMethod(){} func callbackMethod(with notification:

    NSNotification){} func setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: #selector(MyClass.callbackMethod), name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
  136. class MyClass : NSObject { func callbackMethod(){} func callbackMethod(with notification:

    NSNotification){} func setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: #selector(MyClass.callbackMethod(with:)), name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
  137. 0033 - Import Obj-C constants as Swift types

  138. HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMassIndex; HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyFatPercentage;

    HK_EXTERN NSString * const HKQuantityTypeIdentifierHeight; HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMass; HK_EXTERN NSString * const HKQuantityTypeIdentifierLeanBodyMass;
  139. HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMassIndex; HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyFatPercentage;

    HK_EXTERN NSString * const HKQuantityTypeIdentifierHeight; HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMass; HK_EXTERN NSString * const HKQuantityTypeIdentifierLeanBodyMass;
  140. enum HKQuantityTypeIdentifier : String { case BodyMassIndex case BodyFatPercentage case

    Height case BodyMass case LeanBodyMass }
  141. enum HKQuantityTypeIdentifier : String { case BodyMassIndex case BodyFatPercentage case

    Height case BodyMass case LeanBodyMass }
  142. HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMassIndex; HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyFatPercentage;

    HK_EXTERN NSString * const HKQuantityTypeIdentifierHeight; HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMass; HK_EXTERN NSString * const HKQuantityTypeIdentifierLeanBodyMass;
  143. enum HKQuantityTypeIdentifier : String { case BodyMassIndex case BodyFatPercentage case

    Height case BodyMass case LeanBodyMass }
  144. enum HKQuantityTypeIdentifier : String { case BodyMassIndex case BodyFatPercentage case

    Height case BodyMass case LeanBodyMass }
  145. 0005 - Better translation of Obj-C APIs into Swift

  146. let color = NSColor.blueColor()

  147. let color = NSColor.blueColor()

  148. let color = NSColor.blueColor() Prune redundant type names

  149. let color = NSColor.blue()

  150. rootViewController .presentViewController(alert, animated: true, completion: nil)

  151. rootViewController .presentViewController(alert, animated: true, completion: nil) Add default arguments

  152. rootViewController .presentViewController(alert, animated: true, completion: nil) Nullable trailing closures default

    = nil
  153. rootViewController .presentViewController(alert, animated: true)

  154. rootViewController .presentViewController(alert, animated: true) Shouldn't animated default = true

  155. rootViewController.presentViewController(alert)

  156. rootViewController.presentViewController(alert) Prune redundant type names

  157. rootViewController.present(alert)

  158. var empty: Bool

  159. var empty: Bool Prepend "is" to Bools

  160. var isEmpty: Bool

  161. addLineToPoint(myPoint)

  162. addLineToPoint(myPoint) func addLineToPoint(_: CGPoint)

  163. addLineToPoint(myPoint) func addLineToPoint(_: CGPoint) Add first argument labels

  164. addLineToPoint(myPoint) func addLineToPoint(_: CGPoint) Add first argument labels

  165. addLine(to: myPoint) func addLine(to point: CGPoint) Add first argument labels

  166. addLine(to: myPoint) func addLine(to point: CGPoint) Add first argument labels

  167. Add first argument labels

  168. Add first argument labels

  169. var URLHandler

  170. var URLHandler Lower case imported types

  171. var urlHandler Lower case imported types

  172. enum Currency { case Dollars case Euros case Pounds case

    Yen } Lower case imported types
  173. enum Currency { case Dollars case Euros case Pounds case

    Yen } Lower case imported types
  174. enum Currency { case dollars case euros case pounds case

    yen } Lower case imported types
  175. 0036 - Requiring Leading Dot Prefixes for Enum Instance Member

    Implementations
  176. enum Currency { case dollars case euros case pounds case

    yen var symbol: String { switch self { case dollars: return "$" default: return "I don't know" } } }
  177. enum Currency { case dollars case euros case pounds case

    yen var symbol: String { switch self { case .dollars: return "$" default: return "I don't know" } } }
  178. enum Currency { case dollars case euros case pounds case

    yen var symbol: String { switch self { case dollars: return "$" default: return "I don't know" } } }
  179. enum Currency { case dollars case euros case pounds case

    yen var symbol: String { switch self { case .dollars: return "$" default: return "I don't know" } } }
  180. enum Currency { case dollars case euros case pounds case

    yen var symbol: String { switch self { case .dollars: return "$" default: return "I don't know" } } }
  181. 0043 - Declare variables in 'case' labels with multiple patterns

  182. enum MyEnum { case case1(Int,Float) case case2(Float,Int) } switch value

    { case let .case1(x, 2), let .case2(2, x): print(x) case .case1, .case2: break }
  183. enum MyEnum { case case1(Int,Float) case case2(Float,Int) } switch value

    { case let .case1(x, 2), let .case2(2, x): print(x) case .case1, .case2: break }
  184. enum MyEnum { case case1(Int,Float) case case2(Float,Int) } switch value

    { case let .case1(x, 2), let .case2(2, x): print(x) case .case1, .case2: break }
  185. enum MyEnum { case case1(Int,Float) case case2(Float,Int) } switch value

    { case let .case1(x, 2), let .case2(2, x): print(x) case .case1, .case2: break }
  186. enum MyEnum { case case1(Int,Float) case case2(Float,Int) } switch value

    { case let .case1(x, 2), let .case2(2, x): print(x) case .case1, .case2: break }
  187. enum MyEnum { case case1(Int,Float) case case2(Float,Int) } switch value

    { case let .case1(x, 2), let .case2(2, x): print(x) case .case1, .case2: break }
  188. enum MyEnum { case case1(Int,Float) case case2(Float,Int) } switch value

    { case let .case1(x, 2), let .case2(2, x): print(x) case .case1, .case2: break }
  189. 0001 - Allow (most) keywords as argument labels

  190. calculateRevenue(for sales: Int, in currency: Currency)

  191. calculateRevenue(for sales: Int, in currency: Currency)

  192. calculateRevenue(for numberOfCopies, in .dollars)

  193. 0009 - Require self for accessing instance members

  194. struct Friend { let name: String let location: String func

    nameBadge() { print("I'm", name, "from", location) } }
  195. struct Friend { let name: String let location: String func

    nameBadge() { print("I'm", name, "from", location) } }
  196. struct Friend { let name: String let location: String func

    nameBadge() { print("I'm", name, "from", location) } }
  197. struct Friend { let name: String let location: String func

    nameBadge() { print("I'm", self.name, "from", self.location) } }
  198. struct Friend { let name: String let location: String func

    nameBadge() { print("I'm", self.name, "from", self.location) } } Require self for accessing instance members REJECTED
  199. 0011 - Replace typealias keyword with associatedtype for associated type

    declarations
  200. 0011 - Replace typealias keyword with associatedtype for associated type

    declarations
  201. protocol Prot { typealias Container : SequenceType } extension Prot

    { typealias Element = Container.Generator.Element }
  202. protocol Prot { typealias Container : SequenceType } extension Prot

    { typealias Element = Container.Generator.Element }
  203. protocol Prot { associatedtype Container : SequenceType } extension Prot

    { typealias Element = Container.Generator.Element }
  204. 0092 Typealiases in protocols and protocol extensions

  205. protocol Sequence { associatedtype Iterator : IteratorProtocol typealias Element =

    Iterator.Element }
  206. protocol Sequence { associatedtype Iterator : IteratorProtocol typealias Element =

    Iterator.Element }
  207. func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int

    { return sequence.reduce(0, combine: +) }
  208. extension Sequence { typealias Element = Iterator.Element func concat(other: Self)

    -> [Element] { return Array<Element>(self) + Array<Element>(other) } }
  209. extension Sequence { typealias Element = Iterator.Element func concat(other: Self)

    -> [Element] { return Array<Element>(self) + Array<Element>(other) } }
  210. 0048 Generic Type Aliases

  211. typealias StringDictionary<T> = Dictionary<String, T> typealias DictionaryOfStrings<T : Hashable> =

    Dictionary<T, String> typealias IntFunction<T> = (T) -> Int typealias Vec3<T> = (T, T, T) typealias BackwardTriple<T1,T2,T3> = (T3, T2, T1)
  212. typealias StringDictionary<T> = Dictionary<String, T> typealias DictionaryOfStrings<T : Hashable> =

    Dictionary<T, String> typealias IntFunction<T> = (T) -> Int typealias Vec3<T> = (T, T, T) typealias BackwardTriple<T1,T2,T3> = (T3, T2, T1)
  213. typealias StringDictionary<T> = Dictionary<String, T> typealias DictionaryOfStrings<T : Hashable> =

    Dictionary<T, String> typealias IntFunction<T> = (T) -> Int typealias Vec3<T> = (T, T, T) typealias BackwardTriple<T1,T2,T3> = (T3, T2, T1)
  214. typealias StringDictionary<T> = Dictionary<String, T> typealias DictionaryOfStrings<T : Hashable> =

    Dictionary<T, String> typealias IntFunction<T> = (T) -> Int typealias Vec3<T> = (T, T, T) typealias BackwardTriple<T1,T2,T3> = (T3, T2, T1)
  215. typealias StringDictionary<T> = Dictionary<String, T> typealias DictionaryOfStrings<T : Hashable> =

    Dictionary<T, String> typealias IntFunction<T> = (T) -> Int typealias Vec3<T> = (T, T, T) typealias BackwardTriple<T1,T2,T3> = (T3, T2, T1)
  216. 0046 Establish consistent label behavior across all parameters including first

    labels
  217. func increase(ourNumber: Int, delta: Int) -> Int { } increase(6,

    delta: 3)
  218. func increase(ourNumber: Int, delta: Int) -> Int { } increase(6,

    delta: 3)
  219. func increase(ourNumber: Int, delta: Int) -> Int { } increase(6,

    delta: 3)
  220. func increase(ourNumber: Int, delta: Int) -> Int { } increase(6,

    delta: 3)
  221. func increase(ourNumber: Int, delta: Int) -> Int { } increase(ourNumber:

    6, delta: 3)
  222. func increase(_ ourNumber: Int, delta: Int) -> Int { }

    increase(6, delta: 3)
  223. 0023 - Swift API Guidelines

  224. Swift API Design Guidelines

  225. myArray.sort()

  226. sort() sorted()

  227. sortInPlace() sort()

  228. sort() sorted()

  229. sort() sorted() Name functions and methods according to their side-effects

  230. x.distance(to: y) i.successor() Those without side-effects should read as noun

    phrases
  231. x.sort() x.append(y) Those with side-effects should read as imperative noun

    phrases
  232. sort() sorted()/sorting() Use the “ed/ing” rule to name the nonmutating

    counterpart of a mutating method
  233. Prefer methods to free functions

  234. Prefer methods to free functions Protocol Extensions in Swift 2

  235. Prefer methods to free functions Protocol Extensions in Swift 2

    Except …
  236. min(x, y, z) When there's no obvious self

  237. print(x) When the function is an unconstrained generic

  238. sin(x) When the function is part of the established domain

    notation
  239. Methods can share a base name

  240. Methods can share a base name Good when they do

    analogous things
  241. Methods can share a base name Not good (tableView!) when

    they don't
  242. Choose good parameter names

  243. func move(from startingIndex: Int, to endingIndex: Int) Choose good parameter

    names
  244. Take advantage of default values

  245. Take advantage of default values func hello(name: String = "World")

  246. Take advantage of default values init(name: String, hometown: String? =

    nil)
  247. Prefer to locate parameters with defaults at the end init(name:

    String, hometown: String? = nil)
  248. External Argument Labels func move(from startingIndex: Int, to endingIndex: Int)

  249. move(from: here to: there)

  250. Argument Labels Exceptions

  251. min(number1, number2) Omit labels when arguments can't be distinguished

  252. Double(someInt) Omit labels in full width inits

  253. Double(_ anInt: someInt) Omit labels in full width inits

  254. func move(from startingIndex: Int, to endingIndex: Int) When the preposition

    applies to the whole
  255. func moveTo(x: Int, y: Int) When the preposition applies to

    the whole
  256. x.removeBoxes(having Length: 12) When the preposition applies to the whole

  257. Swift 3 focus on source stability

  258. None
  259. None
  260. Next finish Generics stable ABI

  261. None
  262. None
  263. None
  264. None
  265. Understanding Your Toddler iOSConf 2016 Daniel H Steinberg @dimsumthinking