> On Dec 27, 2015, at 1:32 PM, Joe Groff via swift-evolution 
> <[email protected]> wrote:
> 
> Some more things to consider:
> 
> - Our naming conventions encourage the first parameter to most methods to be 
> unlabeled, so unlabeled parameters come up a lot. I don't think there's a 
> grammatical requirement for an identifier before each colon; maybe we can 
> leave out the underscore and use `foo(:bar:)` instead of `foo(_:bar:)` to 
> refer to unlabeled arguments.

At first glance it seems like we can remove the parens altogether if we went 
with this approach. Could instance.`foo:bar:` work (instance.`foo` in the 
no-arg case)? I’m not sure how removing parens would work for inits and 
subscripts though.

> - How do labeled references interact with default and variadic arguments? If 
> you have a func foo(x: Int = 0, y: String = 0), can you refer to foo(x:) and 
> foo(y:) to apply some of the defaulted arguments, or only foo(x:y:)? Would 
> foo(y:x:) also work?
> 
> -Joe
> 
>> On Dec 27, 2015, at 10:37 AM, Joe Groff via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>>> 
>>> On Dec 26, 2015, at 11:22 PM, Douglas Gregor via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>> Hi all,
>>> 
>>> Here’s a proposal draft to allow one to name any function in Swift. In 
>>> effect, it’s continuing the discussion of retrieving getters and setters as 
>>> functions started by Michael Henson here:
>>> 
>>>     
>>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/002168.html
>>>  
>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/002168.html>
>>> 
>>> the proposal follows, and is available here as well:
>>> 
>>>     
>>> https://github.com/DougGregor/swift-evolution/blob/generalized-naming/proposals/0000-generalized-naming.md
>>>  
>>> <https://github.com/DougGregor/swift-evolution/blob/generalized-naming/proposals/0000-generalized-naming.md>
>>> 
>>> Comments appreciated!
>>> 
>>> Generalized Naming for Any Function
>>> 
>>> Proposal: SE-NNNN 
>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0000-generalized-naming.md>
>>> Author(s): Doug Gregor <https://github.com/DougGregor>
>>> Status: Awaiting Review
>>> Review manager: TBD
>>>  
>>> <https://github.com/DougGregor/swift-evolution/blob/generalized-naming/proposals/0000-generalized-naming.md#introduction>Introduction
>>> 
>>> Swift includes support for first-class functions, such that any function 
>>> (or method) can be placed into a value of function type. However, it is not 
>>> possible to specifically name every function that is part of a Swift 
>>> program---one cannot provide the argument labels when naming a function, 
>>> nor are property and subscript getters and setters referenceable. This 
>>> proposal introduces a general syntax that allows one to name anything that 
>>> is a function within Swift in an extensible manner.
>>> 
>>> Swift-evolution thread: Michael Henson started a thread about the 
>>> getter/setter issue here 
>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/002168.html>,
>>>  continued here 
>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/002203.html>.
>>>  See the Alternatives considered 
>>> <https://github.com/DougGregor/swift-evolution/blob/generalized-naming/proposals/0000-generalized-naming.md#alternatives-considered>
>>>  section for commentary on that discussion.
>>> 
>>>  
>>> <https://github.com/DougGregor/swift-evolution/blob/generalized-naming/proposals/0000-generalized-naming.md#motivation>Motivation
>>> 
>>> It's fairly common in Swift for multiple functions or methods to have the 
>>> same "base name", but be distinguished by parameter labels. For example, 
>>> UIView has three methods with the same base name insertSubview:
>>> 
>>> extension UIView {
>>>   func insertSubview(view: UIView, at index: Int)
>>>   func insertSubview(view: UIView, aboveSubview siblingSubview: UIView)
>>>   func insertSubview(view: UIView, belowSubview siblingSubview: UIView)
>>> }
>>> When calling these methods, the argument labels distinguish the different 
>>> methods, e.g.,
>>> 
>>> someView.insertSubview(view, at: 3)
>>> someView.insertSubview(view, aboveSubview: otherView)
>>> someView.insertSubview(view, belowSubview: otherView)
>>> However, when referencing the function to create a function value, one 
>>> cannot provide the labels:
>>> 
>>> let fn = someView.insertSubview // ambiguous: could be any of the three 
>>> methods
>>> In some cases, it is possible to use type annotations to disambiguate:
>>> 
>>> let fn: (UIView, Int) = someView.insertSubview    // ok: uses 
>>> insertSubview(_:at:)
>>> let fn: (UIView, UIView) = someView.insertSubview // error: still ambiguous!
>>> To resolve the latter case, one must fall back to creating a closure:
>>> 
>>> let fn: (UIView, UIView) = { view, otherView in
>>>   button.insertSubview(view, otherView)
>>> }
>>> which is painfully tedious. A similar workaround is required to produce a 
>>> function value for a getter of a property, e.g.,
>>> 
>>> extension UIButton {
>>>   var currentTitle: String? { ... }
>>> }
>>> 
>>> var fn: () -> String? = { () in
>>>   return button.currentTitle
>>> }
>>> One additional bit of motivation: Swift should probably get some way to ask 
>>> for the Objective-C selector for a given method (rather than writing a 
>>> string literal). The argument to such an operation would likely be a 
>>> reference to a method, which would benefit from being able to name any 
>>> method, including getters and setters.
>>> 
>>>  
>>> <https://github.com/DougGregor/swift-evolution/blob/generalized-naming/proposals/0000-generalized-naming.md#proposed-solution>Proposed
>>>  solution
>>> 
>>> Swift currently has a back-tick escaping syntax that lets one use keywords 
>>> for names, which would otherwise fail to parse. For example,
>>> 
>>> func `try`() -> Bool { ... }
>>> declares a function named try, even though try is a keyword. I propose to 
>>> extend the back-tick syntax to allow compound Swift names (e.g., 
>>> insertSubview(_:aboveSubview:)) and references to the accessors of 
>>> properties (e.g., the getter for currentTitle). Specifically,
>>> 
>>> Compound names can be written entirely within the back-ticks, e.g.,
>>> 
>>> let fn = someView.`insertSubview(_:at:)`
>>> let fn1 = someView.`insertSubview(_:aboveSubview:)`
>>> The same syntax can also refer to initializers, e.g.,
>>> 
>>> let buttonFactory = UIButton.`init(type:)`
>> This part seems reasonable to me.
>>> Getters and setters can be written using dotted syntax within the 
>>> back-ticks:
>>> 
>>> let specificTitle = button.`currentTitle.get` // has type () -> String?
>>> let otherTitle = UIButton.`currentTitle.get`  // has type (UIButton) -> () 
>>> -> String?
>>> let setTintColor = button.`tintColor.set`     // has type (UIColor!) -> ()
>>> The same syntax works with subscript getters and setters as well, using the 
>>> full name of the subscript:
>>> 
>>> extension Matrix {
>>>   subscript (row row: Int) -> [Double] {
>>>     get { ... }
>>>     set { ... }
>>>   }
>>> }
>>> 
>>> let getRow = someMatrix.`subscript(row:).get` // has type (Int) -> () -> 
>>> [Double]
>>> let setRow = someMatrix.`subscript(row:).set` // has type (Int) -> 
>>> ([Double]) -> ()
>> At least as far as pure Swift is concerned, for unapplied access, like 
>> `UIButton.currentTitle`, I think it would be more consistent with the way 
>> method references works for that to give you the getter (or lens) without 
>> decoration. instance.instanceMethod has type Args -> Ret, and 
>> Type.instanceMethod has type Self -> Args -> Ret; by analogy, since 
>> instance.instanceProperty has type Ret or inout Ret, it's reasonable to 
>> expect Type.instanceProperty to have type Self -> [inout] Ret. Forming a 
>> getter or setter partially applied to an instance feels unmotivated to me—{ 
>> button.currentTitle } or { button.currentTitle = $0 } already work, and are 
>> arguably clearer than this syntax.
>> 
>> I acknowledge that this leaves forming selectors from setters out to dry, 
>> but I feel like that's something that could be incorporated into a "lens" 
>> design along with typed selectors. As a rough sketch, we could say that the 
>> representation of @convention(selector) T -> inout U is a pair of 
>> getter/setter selectors, and provide API on Selector to grab the individual 
>> selectors from that, maybe Selector(getterFor: 
>> UIView.currentTitle)/(setterFor: UIView.currentTitle). I don't think get/set 
>> is a good interface for working with Swift properties, so I don't like the 
>> idea of building in language support to codify it beyond what's needed for 
>> ObjC interaction.
>>> Can we drop the back-ticks? It's very tempting to want to drop the 
>>> back-ticks entirely, because something like
>>> 
>>> let fn = someView.insertSubview(_:at:)
>>> can be correctly parsed as a reference to insertSubview(_:at:). However, it 
>>> breaks down at the margins, e.g., with getter/setter references or 
>>> no-argument functions:
>>> 
>>> extension Optional {
>>>   func get() -> T { return self! }
>>> }
>>> 
>>> let fn1 = button.currentTitle.get   // getter or Optional<String>.get?
>>> let fn2 = set.removeAllElements()   // call or reference?
>> From what I remember, the bigger concern with allowing foo(bar:bas:) without 
>> backticks is parser error recovery. The unambiguity with call syntax depends 
>> on having the `:)` token pair at the end. The edit distance between 
>> foo(bar:bas:) and a call foo(bar: bas) or work-in-progress call foo(bar: x, 
>> bas: ) is pretty slight, and would be tricky to give good diagnostics for. 
>> If we felt confident we could give good diagnostics, I'd support removing 
>> the backticks.
>> 
>> -Joe
>> 
>>  _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to