www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 1182] New: Mixins scope

reply d-bugmail puremagic.com writes:
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.


-- 
Apr 24 2007
next sibling parent reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1182


bugzilla digitalmars.com changed:

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





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.


-- 
Apr 24 2007
parent Aarti_pl <aarti interia.pl> writes:
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... :-)
Apr 24 2007
prev sibling next sibling parent reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1182






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);
}


-- 
Apr 24 2007
parent Aarti_pl <aarti interia.pl> writes:
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.


  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.
Apr 24 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1182


aarti interia.pl changed:

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





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.)


-- 
Apr 24 2007
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1182






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).


-- 
Apr 27 2007