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