> On Dec 29, 2015, at 12:17 PM, Joe Groff via swift-evolution 
> <swift-evolution@swift.org> 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?
> 
> 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`()
>   }
> }
> 

Like many others I am not a fan of the backticks being required in common use 
cases, but I don’t mind them in edge cases at all.  In those cases they are far 
better than no solution.  So +1 to using backticks to allow disambiguation!

> -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
> 
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> 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