Swift 2.0b4: Curried initializer syntax
Originator: | rix.rob | ||
Number: | rdar://22108354 | Date Originated: | 02-Aug-2015 04:07 PM |
Status: | Open | Resolved: | |
Product: | Developer Tools | Product Version: | Xcode-beta (7A165t) |
Classification: | Enhancement | Reproducible: | Always |
Summary: Functions have a curried syntax allowing convenient definition of functions returning functions: func add(x: Int)(_ y: Int) -> Int { return x + y } The same syntax would be useful for defining initializers: struct Add { init(_ x: Int)(_ y: Int) { self.x = x self.y = y } let x: Int let y: Int } The above initializer would be equivalent to a static function: struct Add { static func init_(x: Int)(_ y: Int) -> Add { return Add(x: x, y: y) } let x: Int let y: Int } For example it can be partially applied, returning a function which initializes new instances of the type: let incremented = [0, 1, 2, 3, 4].map(Add(1)) // equivalently: .map(Add.init(1)) This would also allow failable initialization in the usual way: struct Pair<A, B> { init?(x: A?)(y: B?) { guard let x = x else { return nil } guard let y = y else { return nil } left = x right = y } let left: A let right: B } This would yield an initializer of type A? -> B? -> Pair<A, B>?, i.e. the semantics are again identical to a curried static function defined over an uncurried (failable) initializer: struct Pair<A, B> { static func init_(x: A?)(y: B?) -> Pair { return Pair(x: x, y: y) } init?(x: A?, y: B?) { guard let x = x else { return nil } guard let y = y else { return nil } left = x right = y } let left: A let right: B } This syntax would enable more idiomatic curried construction of Swift types than is currently possible. For example, my motivating case is the family of `loc` functions defined here: https://github.com/antitypical/Manifold/blob/289e8444349c9d3bf7d02cefde7db08966134f69/Manifold/Location.swift#L46-L79 Taking the first function as an example, we could define it in extant Swift 2 syntax as a failable initializer, something like so (🚨 untested 🚨): init?(_ weave: (A -> Location?) -> A -> Location?, _ up: A -> Location?, _ a: A) { func into(t1: A) -> Location? { return Location(it: t1, down: weave(into), up: up, left: const(nil), right: const(nil)) } self = into(a) } However, in doing so we would lose the ability to partially apply it, which is depended upon elsewhere in the codebase. Steps to Reproduce: N/A Expected Results: N/A Actual Results: N/A Regression: N/A Notes: N/A
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!