Right.

Félix

> Le 29 déc. 2015 à 15:04:11, Douglas Gregor <dgre...@apple.com> a écrit :
> 
> 
> 
> Sent from my iPhone
> 
> On Dec 29, 2015, at 11:48 AM, Félix Cloutier <felix...@yahoo.ca 
> <mailto:felix...@yahoo.ca>> 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 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> 
>>>> 
>>>> Sent from my iPhone
>>>> 
>>>> On Dec 29, 2015, at 10:17 AM, Joe Groff <jgr...@apple.com 
>>>> <mailto:jgr...@apple.com>> 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 
>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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:)`
>>>>>> 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:
>>>>>>  
>>>>>> <https://github.com/DougGregor/swift-evolution/blob/generalized-naming/proposals/0000-generalized-naming.md#impact-on-existing-code>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.
>>>>>> 
>>>>>>  
>>>>>> <https://github.com/DougGregor/swift-evolution/blob/generalized-naming/proposals/0000-generalized-naming.md#alternatives-considered>Alternatives
>>>>>>  considered
>>>>>> 
>>>>>> Michael Henson proposed 
>>>>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/002168.html>
>>>>>>  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 
>>>>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/002210.html>.
>>>>>>  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 
>>>>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/003008.html>
>>>>>>  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
>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>>  _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to