Thread overview
[Issue 1182] New: Mixins scope
Apr 24, 2007
d-bugmail
Apr 24, 2007
d-bugmail
Apr 24, 2007
Aarti_pl
Apr 24, 2007
d-bugmail
Apr 24, 2007
Aarti_pl
Apr 24, 2007
d-bugmail
Apr 27, 2007
d-bugmail
April 24, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1182

           Summary: Mixins scope
           Product: D
           Version: 1.013
          Platform: PC
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: aarti@interia.pl


Spec: Mixin Scope
The declarations in a mixin are 'imported' into the surrounding scope. If the
name of a declaration in a mixin is the same as a declaration in the
surrounding scope, the surrounding declaration overrides the mixin one.

---
Mixins should not only compare name with existing symbols in current scope, but in case of functions also parameters. It will allow proper function overloading. Currently following test case fails to compile:

import std.stdio;
template TestTemplate(T) {
    T policy(int i) { return T.init;}
    int policy() { return 1; }
}
class TestClass {
    mixin TestTemplate!(TestClass);
    TestClass policy(int i) { return this; }
}
void main() {
    writefln((new TestClass).policy);
}
---

It is quite painful limitation of mixins, and IMHO should be bug. I put it as enhancement because it conforms literal interpretation of specs.


-- 

April 24, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1182


bugzilla@digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID




------- Comment #1 from bugzilla@digitalmars.com  2007-04-24 04:02 -------
It isn't a bug, it's meant to behave this way. If you want to overload mixin names with the surrounding scope name, you can use an 'alias' in the same manner one would use alias to merge the overload sets of two imported modules.


-- 

April 24, 2007
How to make alias definition with anonymous mixin and function?
I can understand how to do it with named mixins but with my example? I did not found similar example here on NG...

Could you please just correct my test case? One example is worth more than thousand words... :-)
April 24, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1182





------- Comment #3 from bugzilla@digitalmars.com  2007-04-24 05:21 -------
You can't do it with anonymous mixins, they have to be named.

import std.stdio;
template TestTemplate(T) {
    T policy(int i) { return T.init;}
    int policy() { return 1; }
}
class TestClass {
    mixin TestTemplate!(TestClass) foo;
    alias foo.policy policy;
    TestClass policy(int i) { return this; }
}
void main() {
    writefln((new TestClass).policy);
}


-- 

April 24, 2007
First: How does it work? There are two policy symbols in template (overloaded functions). Why 'getter property' is choosen? How to choose setter?

Second: That's solution far from good. Imagine you have e.g. 10 symbols inserted by mixin (I work with such a case.). What's more mixins are inserted into many inherited classes. You need to alias all symbols inside mixin template in every inherited class.

Third: Would be also great to implement anchored types (#1120). It would  depreciate this use-case for mixins.

I request to leave that enhancement open. Simply enhancing rule of inserting anonymous mixin into scope for function names *AND* their arguments would solve problem cleanly.
April 24, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1182


aarti@interia.pl changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|INVALID                     |




------- Comment #5 from aarti@interia.pl  2007-04-24 06:39 -------
Maybe I was not enough clear with my enhancement idea. I think that original test case doesn't work because when compiler is mixing in template, it checks if symbol 'policy' exists. According to specs when in current scope symbol exists, symbol from mixin template should be dropped. It works good in general case (and is really useful), but doesn't work in my example. When checking for symbol compiler just doesn't check parameters of function and thinks that symbol 'policy' is already there. If checking symbol could also include checking parameters, method from template:

int policy() { return 1; }

could be normally inserted in the scope of TestClass. (But method T policy(int
i) { return T.init;} from template would be still droped, as it is *exactly*
same as in TestClass scope.)


-- 

April 27, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1182





------- Comment #6 from aarti@interia.pl  2007-04-27 02:34 -------
It seems that your example works just because there is template function used. In general case it fails, so it is no solution to problem. Consider following example:

import std.stdio;
template TestTemplate() {
    int policy() { return 0; }
    int policy(int a) { return 1;}
    int policy(int a, int b) { return 2;}
}
class TestClass {
    mixin TestTemplate!() foo;
    alias foo.policy policy;
    int policy(int a) { return 11; }
}
void main() {
    writefln((new TestClass).policy);       //(1) Ok.
    //writefln((new TestClass).policy(1));  //(2) ambiguity
    writefln((new TestClass).policy(1,1));  //(3) Ok.
}

It would be possible to overcome this if you could alias specific symbol /method e.g.:

alias foo.policy(int, int) policy;

It seems that best solution is to extend rules of symbol matching. I would be happy to see it also in case of inheritance (see thread on bugs NG).


--