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

L Mihalkovic laurent.mihalkovic at gmail.com
Thu Jun 9 12:46:14 CDT 2016


> On Jun 9, 2016, at 7:04 PM, Jordan Rose <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")
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160609/27feb999/attachment.html>


More information about the swift-evolution mailing list