digitalmars.D - PROPOSAL: Fully-qualified names to extend overload sets
- Russell Lewis (66/66) May 09 2008 First, if you aren't familiar with the issue, read
- Paul D. Anderson (3/31) May 12 2008 Just wanted to bump this because it seemed like it was worth discussing ...
- Russell Lewis (9/13) May 12 2008 Let me restate this in a better way (I really struggled to explain it in...
First, if you aren't familiar with the issue, read http://www.digitalmars.com/d/2.0/function.html#overload-sets . As has been discussed before in the NG, we have the concept of overload sets because we don't want 2 modules which accidentally use the same function names to end up confusing each other's overload rules. (Similarly, we have the problem with classes...if you define a function that shares a name with some deeply-buried class in a library, are you overloading the function, or accidentally defining a coincidence?) The workaround, if you want to merge two moduless' sets, is to use "alias" declarations in one of them. However, I think that I have a better idea. Let's say that a fully-qualified name (a.b.c.myFunc) functions as a symbol which is distinct from any non-qualified name (myFunc). Now, we can use that symbol in any *other* module to explicitly say "this new thing that I'm defining is an overload of that other known thing." Likewise, when you *use* the symbol, you are accessing the entire overload set (including the add-ons). (NOTE: Since the original module doesn't know about any of its add-ons, you are only overloading using the things that you have defined using your imports. See example below.) EXAMPLE CODE (PROPOSED SYNTAX) "a.d" int myFunc(int); "b.d" import a; int a.myFunc(char); "c.d" import a; a.myFunc('x'); // calls a.myFunc(int) "d.d" import a; import b; a.myFunc('x'); // calls b.myFunc(char) END CODE Advantages: * Import any new module and add overloads to an *old* overload set * Access the entire overload set (including add-ons) with the name of the root. Think about the canonical example of a "Shape" class... * Easily handles the case where you have 2 add-on modules to the same base module (hard to do with 'alias'). CLASSES This has immediate applicability to classes. An easy syntax for overloading would be to reference the (original) base class or interface where the overloaded-function was defined. If you don't provide that name, then D would assume that this is a new, unrelated function. (Question: How would we handle the gradual transition to this model?) EXAMPLE CODE (PROPOSED) library.d: class A { int foo(); } class B : A { int A.foo(); // overloads A.foo } myProgram.d: import library; class C : B { int foo(); // UNRELATED to A.foo! } A myVar = new C; myVar.foo(); // calls B.foo() C myVar_C = cast(C)myVar; myVar.foo(); // calls C.foo() THOUGHTS?
May 09 2008
Russell Lewis Wrote:EXAMPLE CODE (PROPOSED) library.d: class A { int foo(); } class B : A { int A.foo(); // overloads A.foo } myProgram.d: import library; class C : B { int foo(); // UNRELATED to A.foo! } A myVar = new C; myVar.foo(); // calls B.foo() C myVar_C = cast(C)myVar; myVar.foo(); // calls C.foo() THOUGHTS?Just wanted to bump this because it seemed like it was worth discussing but got lost in the high traffic of the weekend. Paul
May 12 2008
Russell Lewis wrote:Likewise, when you *use* the symbol, you are accessing the entire overload set (including the add-ons). (NOTE: Since the original module doesn't know about any of its add-ons, you are only overloading using the things that you have defined using your imports. See example below.)Let me restate this in a better way (I really struggled to explain it in my original post): The idea is that when you use an unqualified name, this name is mapped by the compiler to some fully-qualified name (basically like current overload sets work). We then calculate the set of possible overloads as if the user had used the fully-qualified name. Of course, just like the current overload sets design, if there is any ambiguity, then the compiler produces an error.
May 12 2008