[swift-evolution] Name disambiguation of computed property/function with same type defined in extensions

Jordan Rose jordan_rose at apple.com
Thu Jun 9 13:14:29 CDT 2016


> On Jun 9, 2016, at 11:12, L Mihalkovic <laurent.mihalkovic at gmail.com> wrote:
> 
>> 
>> On Jun 9, 2016, at 8:01 PM, Thorsten Seitz <tseitz42 at icloud.com <mailto:tseitz42 at icloud.com>> wrote:
>> 
>>> 
>>> Am 09.06.2016 um 19:46 schrieb L Mihalkovic via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>>:
>>> 
>>>> 
>>>> On Jun 9, 2016, at 7:04 PM, Jordan Rose <jordan_rose at apple.com <mailto:jordan_rose at apple.com>> wrote:
>>>> 
>>>>> 
>>>>> On Jun 9, 2016, at 07:35, L. Mihalkovic <laurent.mihalkovic at gmail.com <mailto:laurent.mihalkovic at gmail.com>> wrote:
>>>>> 
>>>>> 
>>>>> On Jun 9, 2016, at 3:27 AM, Jordan Rose via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>> 
>>>>>> Hi, Paulo. Thanks for bringing this up; it’s definitely an interesting problem to solve.
>>>>>> 
>>>>>> My thoughts are mostly in line with yours, that disambiguation at the call site is the most Swift-like thing to do, at least as a first step. Maybe we can add some way to record general preferences, or maybe just asking people to define a wrapper function to put the disambiguation in one place is fine.
>>>>>> 
>>>>>> I’m not particularly a fan of the “from” syntax or the “@“ syntax, but I don’t have anything better. (And the “not a fan” is entirely a taste thing, plus a general desire not to steal new keywords or operator characters. Neither of these are blockers.) I’ve been playing with silly things like this:
>>>>>> 
>>>>>> str.(ModuleA.capitalized)()
>>>>>> 
>>>>> 
>>>>> Seeing all these proposals that people make, it makes me thinks that extensions as they exist are not fully understood... People seem to consider them  like the Xtext/Xtend/c# extension METHODS, which means that maybe they should also be added to Swift, and people would not be confused:
>>>>> 
>>>>> public static func capitalized(self:String)() {}    
>>>>> 
>>>>> Then these would be easily individually imported from module x,y or z with the current syntax, and then "extension String {}" would retain it current scoping behavior
>>>>> 
>>>>> No matter what, I think many extensions are just a bad outlook on OOD, but properly understood, they are great.
>>>> 
>>>> I’m not sure what you mean. How does changing the declaration site solve the disambiguation problem at the call site? (And how do you think Swift extensions differ from C# extensions?)
>>>> 
>>> 
>>> sorry, I thought the example was clearer than it actually is (pb with writing thgs in a train)
>>> 
>>> 
>>> This is code I wrote a couple weeks ago (parsing some WWDC related things in C#):
>>> namespace HtmlAgilityPackPlus {
>>>     using HtmlAgilityPack;
>>> 
>>>     public static class Extender {
>>>         public static HtmlNode ChildOfType(this HtmlNode node, string name) {
>>>             var n = node.ChildNodes.Where( x => x.Name == name).First();
>>>             return n;
>>>         }         
>>>         public static HtmlNode FirstLink(this HtmlNode node) {
>>>             var child = node.ChildOfType("a");
>>>             return child;
>>>         }
>>>         public static HtmlNode FirstDescendantMatching(this HtmlNode node, Func<HtmlNode, bool> predicate) {
>>>             var seq = node.Descendants().Where( x => predicate(x) );
>>>             return ((seq?.Count() ?? 0) > 0) ? seq.First() : null;
>>>         }
>>>     }
>>> }
>>> 
>>> XText and XTend work the same (I think at some point so did kotlin, but I haven’t checked since the final)
>>> 
>>> 
>>> Now this is some Swift code (yes I am not bothering with the details)
>>> module A ===
>>> 
>>> extension String {
>>>     func oneA() {  }
>>>     func twoA() {  }
>>>     func threeA() {  }
>>> }
>>> 
>>> 
>>> module B ===
>>> 
>>> extension String {
>>>     func oneB() {  }
>>>     func twoB() {  }
>>>     func threeB() {  }
>>> }
>>> 
>>> We could say that the Swift extension is a ‘batch’ oriented mechanism: 
>>> first a target type is decided by forming a scope
>>> then many extension methods can be added together
>>> Of course one can also add a single method at a time in as many single scopes. But the fact remains.. the syntax is oriented towards 
>>> anonymity of the source
>>> batch adds
>>> 
>>> as you can see, this is not how C# works.
>>> 
>>> So now, given that context, I was suggesting that people seem to consider Swift extensions as something they currently are NOT: there is no way to pinpoint a particular extension in a particular module (import the module, inherit its extensions), there is NO way to target a given method in a given extension in a given module.
>>> 
>>> 
>>> My point was to suggest that it may show that current extensions are invaluable for something like the adapter pattern (than you E. Gamma), but not entirely suited for the more fine-grained scenario that people keep use in the mail thread.
>>> 
>>> This led to my proposal to ALSO support (not REPLACE) 
>>> 
>>> module A ===
>>> extension String {
>>>     func oneA() {  }
>>>     func twoA() {  }
>>>     func threeA() {  }
>>> }
>>> // more like the GO syntax
>>> public static func indexOfSubStringInReversedOrder(self:String)(pattern:String) -> Int {}    
>>> 
>>> 
>>> module B ===
>>> extension String {
>>>     func oneB() {  }
>>>     func twoB() {  }
>>>     func threeB() {  }
>>> }
>>> // more like the c#/XText/XTend/... syntax
>>> public static func indexOfSubStringInReversedOrder(self:String, pattern:String) -> Int {}    
>>> 
>>> because we can now do the following without altering anything
>>> 
>>> import func moduleA.indexOfSubStringInReversedOrder
>>> var idx = "blahblahXYZblah".indexOfSubStringInReversedOrder("zyx")
>>> _______________________________________________
>> 
>> 
>> What hinders me in the case of Swift’s extensions to write
>> 
>> import func moduleA.String.oneB
>> 
>> This would achieve just the same thing.
>> 
> 
> hmmm….. I know… tempting, right?!    but how then does this not DESTROY the other behavior?!  “compiler, be smart… if I say nothing, then let the runtime loader import everything everywhere because it is still very useful even if I don’t want to recognize it right now. But then if I start to import something, then tell the runtime loader that he has to stop mocking about with all these extension blocks to String that he will find and just add the one method that I care about. and btw, remember to the other thing in all my other source files” I look forward to read the source code that will make it work, because I know I do not have the beginning of the imagination required to have a clue how it will look like.

I'm really not sure what you're talking about. Extension methods are resolved at compile-time, not run-time. (Except @objc extension methods, which are as dangerous as categories ever were, and which isn't changing.)

Jordan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160609/4fdd03e1/attachment.html>


More information about the swift-evolution mailing list