Sent from my iPhone

> On Dec 29, 2015, at 11:48 AM, Félix Cloutier <[email protected]> wrote:
> 
> Currently, they can be disambiguated using (self as ProtocolA).bar(), no?

Not if ProtocolA has self requirements or associated types. 
> 
> Félix
> 
>> Le 29 déc. 2015 à 14:10:51, Erica Sadun via swift-evolution 
>> <[email protected]> a écrit :
>> 
>> Talk about things you didn't know you needed until you see them. This is a 
>> really nice way of disambiguating!
>> 
>> -- E
>> 
>>> On Dec 29, 2015, at 12:03 PM, Douglas Gregor via swift-evolution 
>>> <[email protected]> wrote:
>>> 
>>> 
>>> 
>>> Sent from my iPhone
>>> 
>>>> On Dec 29, 2015, at 10:17 AM, Joe Groff <[email protected]> wrote:
>>>> 
>>>> We also have a problem with disambiguating same-named members that come 
>>>> from different extensions, whether via protocol extensions or independent 
>>>> concrete extensions from different modules. Could we extend this scheme to 
>>>> allow for disambiguating extension methods by protocol/module name?
>>> 
>>> That's a fantastic idea!
>>> 
>>>> 
>>>> extension ProtocolA { func foo() }
>>>> extension ProtocolB { func foo() }
>>>> 
>>>> public struct Foo: ProtocolA, ProtocolB {
>>>>   func callBothFoos() {
>>>>     self.`ProtocolA.foo`()
>>>>     self.`ProtocolB.foo`()
>>>>   }
>>>> }
>>>> 
>>>> import A // extends Bar with bar()
>>>> import B // also extends Bar with bar()
>>>> 
>>>> extension Bar {
>>>>   func callBothBars() {
>>>>     self.`A.bar`()
>>>>     self.`B.bar`()
>>>>   }
>>>> }
>>>> 
>>>> -Joe
>>>> 
>>>>> 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

Reply via email to