Looks good so far.

Top-level functions:

#doSomething()
ModuleName#doSomething() // is it a problem to distinguish modules and classes 
here?

What about static/class functions? Any idea how to fit them into that scheme?

-Thorsten

> Am 28.12.2015 um 16:05 schrieb T.J. Usiyan via swift-evolution 
> <[email protected]>:
> 
> Do things get any better if we combine the proposed changes and remove the 
> bare case? Begin function reference with some symbol (# here but it doesn't 
> matter), only use back tics to disambiguate keywords (which lines up with 
> their current use) and remove the unadorned case to avoid ambiguity.
> 
> ```swift 
> class Foo {
>       func doSomething() { }
>       func doSomething(value: Int) { }
>       func sub
> }
> 
> let fn = Foo#doSomething // no longer allowed
> let fn = Foo#doSomething() // okay
> let fn2 = Foo#doSomething(_:) // okay
> 
> // and
> 
> let getRow = someMatrix#`subscript`(row:).get
> 
> ```
> 
> 
> 
>> On Sun, Dec 27, 2015 at 10:40 PM, Douglas Gregor via swift-evolution 
>> <[email protected]> wrote:
>> 
>>> On Dec 27, 2015, at 12:27 AM, Frederick Kellison-Linn via swift-evolution 
>>> <[email protected]> wrote:
>>> 
>>> Given that someView.insertSubview(_:at:) can be correctly parsed, I would 
>>> strongly lean towards the no-backtick alternative mentioned at the end. I 
>>> feel as though the backticks end up looking very cluttered (particularly 
>>> when you get into the double-nested backticks), and it seems cleaner to be 
>>> able to reference a method as it was declared rather than having to add 
>>> extra syntax.
>>> 
>>> In reference to the issues noted with this approach:
>>> 
>>> IMO, there is already enough syntactic difference between getters/setters 
>>> and normal methods to justify requiring a different syntax to reference 
>>> them. For instance, the # syntax could be used so that, 
>>> button.currentTitle.get would reference Optional<String>.get, and 
>>> button.currentTitle#get would reference the getter. Or, 
>>> button.`currentTitle.get` could reference the getter (i.e. backticks are 
>>> only required in cases that are ambiguous).
>>> 
>>> I also think it is reasonable to require that in the case of a method with 
>>> no arguments such as set.removeAllElements, the programmer be expected to 
>>> know the difference between the expression with and without the trailing 
>>> parenthesis. After all, that distinction already exists in the language, 
>>> and would not disappear with this proposed addition. If a parallel syntax 
>>> for referencing methods with no arguments is strongly desired, perhaps 
>>> something such as set.removeAllElements(:), set#removeAllElements(), or 
>>> similar could be used, though I think that the present system for 
>>> referencing these methods is sufficient.
>>> 
>>> Are there other obvious reasons why this alternative wouldn’t work? I think 
>>> it is the cleanest of the alternatives and avoids littering the code with 
>>> backticks.
>> 
>> Not having the back-ticks means that you will need to use contextual type 
>> information to disambiguate the zero-parameter case from other cases. For 
>> example:
>> 
>>      class Foo {
>>              func doSomething() { }
>>              func doSomething(value: Int) { }
>>      }
>> 
>>      let fn = Foo.doSomething // ambiguous
>>      let fn2 = Foo.doSomething(_:) // okay
>>      let fn3: (Foo) -> () -> Void = Foo.doSomething // okay
>>      let fn3: (Foo) -> (Int) -> Void = Foo.doSomething // okay
>> 
>> My general complaint with the “drop the backticks” approach is that it 
>> doesn’t solve the whole problem. Sure, it solves 95% of the problem with a 
>> little less syntax, but now you need to invent yet another mechanism to 
>> handle the other cases (#set, contextual type disambiguation, etc)… which 
>> seems inconsistent to me.
>> 
>>      - Doug
>> 
>> 
>>>> On Dec 26, 2015, at 11:22 PM, Douglas Gregor via swift-evolution 
>>>> <[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
>>>> 
>>>> the proposal follows, and is available here as well:
>>>> 
>>>>    
>>>> https://github.com/DougGregor/swift-evolution/blob/generalized-naming/proposals/0000-generalized-naming.md
>>>> 
>>>> Comments appreciated!
>>>> 
>>>> Generalized Naming for Any Function
>>>> 
>>>> Proposal: SE-NNNN
>>>> Author(s): Doug Gregor
>>>> Status: Awaiting Review
>>>> Review manager: TBD
>>>> 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, continued here. See the Alternatives considered 
>>>> section for commentary on that discussion.
>>>> 
>>>> 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.
>>>> 
>>>> 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:)`
>>>> 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]) -> ()
>>>> If we introduce property behaviors into Swift, the back-tick syntax could 
>>>> also be used to refer to behaviors, e.g., accessing the lazy behavior of a 
>>>> property:
>>>> 
>>>> self.`myProperty.lazy`.clear()
>>>> Base names that are meaningful keywords (init and subscript) can be 
>>>> escaped with a nested pair of back-ticks:
>>>> 
>>>> extension Font {
>>>>   func `subscript`() -> Font {
>>>>     // return the subscript version of the given font
>>>>   }
>>>> }
>>>> 
>>>> let getSubscript = font.``subscript`()` // has type () -> Font
>>>> The "produce the Objective-C selector for the given method" operation will 
>>>> be the subject of a separate proposal. However, here is one possibility 
>>>> that illustrations how it uses the proposed syntax here:
>>>> 
>>>> let getter: Selector = objc_selector(NSDictionary.`subscript(_:).get`) // 
>>>> produces objectForKeyedSubscript:
>>>> let setter: Selector = objc_selector(NSDictionary.`subscript(_:).set`) // 
>>>> produces setObject:forKeyedSubscript:
>>>> Impact on existing code
>>>> 
>>>> This is a purely additive feature that has no impact on existing code. The 
>>>> syntactic space it uses is already present, and it merely extends the use 
>>>> of back-ticks from storing a single identifier to more complex names.
>>>> 
>>>> Alternatives considered
>>>> 
>>>> Michael Henson proposed naming getters and setters using # syntax followed 
>>>> by get or set, e.g.,
>>>> 
>>>> let specificTitle = button.currentTitle#get
>>>> The use of postfix # is a reasonable alternative here, and more 
>>>> lightweight than two back-ticks for the simple getter/setter case. The 
>>>> notion could be extended to allow argument labels for functions, discussed 
>>>> here. The proposals in that discussion actually included type annotations 
>>>> as well, but the syntax seems cleaner---and more directly focused on 
>>>> names---without them, e.g.,:
>>>> 
>>>> let fn = someView.insertSubview#(_:at:)
>>>> which works. I didn't go with this syntax because (1) it breaks up Swift 
>>>> method names such as insertSubview(_:at:)with an # in the middle, and (2) 
>>>> while useful, this feature doesn't seem important enough to justify 
>>>> overloading #further.
>>>> 
>>>> Joe Groff notes that lenses are a better solution than manually retrieving 
>>>> getter/setter functions when the intent is to actually operate on the 
>>>> properties. That weakens the case this proposal makes for making 
>>>> getters/setters available as functions. However, it doesn't address the 
>>>> general naming issue or the desire to retrieve the Objective-C selector 
>>>> for a getter/setter.
>>>> 
>>>> 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?
>>>> 
>>>> 
>>>>    - Doug
>>>> 
>>>> 
>>>> _______________________________________________
>>>> 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
>> 
>> 
>> 
>> _______________________________________________
>> 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
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to