www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - string mixins shadowing names

reply Timon Gehr <timon.gehr gmx.ch> writes:
consider:

string foo(){
     return q{pragma(msg,"foo");};
}
struct T{
     mixin(foo());
     mixin(q{
         static string foo(){
              return q{pragma(msg,"T.foo");};
         }
     });
}

this prints "foo";

versus:

string foo(){
     return q{pragma(msg,"foo");};
}
struct T{
     mixin(q{
         static string foo(){
              return q{pragma(msg,"T.foo");};
         }
     });
     mixin(foo());
}

which prints "T.foo" with DMD 2.054.

To make mixins less bug prone and hacky, I suggest to disallow shadowing 
any declaration that is referred to in a mixin declaration in the same 
scope.


Another example that demonstrates how weird the current lookup rules are:


string foo(){
     return q{pragma(msg,foo);};
}

struct T{
     static string qux(){return foo();} // this refers to T.foo.
     mixin(q{ // this mixin shadows foo
         static string foo(){
              return q{pragma(msg,"T.foo");};
         }
     });
     mixin(qux());
}

---

string foo(){
     return q{pragma(msg,foo);};
}

struct T{
     static string qux(){return foo();} // this refers to foo
     mixin(qux()); // because this is evaluated first now.
     mixin(q{ // this mixin shadows foo
         static string foo(){
              return q{pragma(msg,"T.foo");};
         }
     });
}


I am strongly in favor of disallowing any cases where mixin declarations 
shadow declarations that were used to compute mixin declarations in a 
scope that allows forward references.


Any thoughts on this?
Sep 07 2011
next sibling parent reply Christian Kamm <kamm-incasoftware removethis.de> writes:
Timon Gehr wrote:
 I am strongly in favor of disallowing any cases where mixin declarations
 shadow declarations that were used to compute mixin declarations in a
 scope that allows forward references.
 
 
 Any thoughts on this?

Order-of-static-evaluation problems are not limited to mixins: static if (!is(typeof(foo)) enum bar = 1; static if (!is(typeof(bar)) enum foo = 1; with the way dmd handles forward references, this can go either way depending on which static if gets evaluated first. D's wish that 'the order of declarations does not matter' is impossible to fulfill due to mixins and static if. They are special because they can alter the symbol table based on the contents of the symbol table. I think you could get away with defining that 'the order of declarations does not matter - except for static if and mixin which always get evaluated in lexical order'. I'm not sure how much work it'd be to make dmd behave that way. It probably wouldn't be worthwile.
Sep 08 2011
next sibling parent reply Don <nospam nospam.com> writes:
On 08.09.2011 17:26, Christian Kamm wrote:
 Timon Gehr wrote:
 I am strongly in favor of disallowing any cases where mixin declarations
 shadow declarations that were used to compute mixin declarations in a
 scope that allows forward references.


 Any thoughts on this?

Order-of-static-evaluation problems are not limited to mixins: static if (!is(typeof(foo)) enum bar = 1; static if (!is(typeof(bar)) enum foo = 1; with the way dmd handles forward references, this can go either way depending on which static if gets evaluated first. D's wish that 'the order of declarations does not matter' is impossible to fulfill due to mixins and static if. They are special because they can alter the symbol table based on the contents of the symbol table. I think you could get away with defining that 'the order of declarations does not matter - except for static if and mixin which always get evaluated in lexical order'. I'm not sure how much work it'd be to make dmd behave that way. It probably wouldn't be worthwile.

I prefer: The order of declarations NEVER matters, and the above code is illegal. It's easy to implement.
Sep 15 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09/15/2011 06:01 PM, Jonathan M Davis wrote:
 On Thursday, September 15, 2011 14:59:29 Don wrote:
 On 08.09.2011 17:26, Christian Kamm wrote:
 Timon Gehr wrote:
 I am strongly in favor of disallowing any cases where mixin
 declarations
 shadow declarations that were used to compute mixin declarations in a
 scope that allows forward references.


 Any thoughts on this?

Order-of-static-evaluation problems are not limited to mixins: static if (!is(typeof(foo)) enum bar = 1; static if (!is(typeof(bar)) enum foo = 1; with the way dmd handles forward references, this can go either way depending on which static if gets evaluated first. D's wish that 'the order of declarations does not matter' is impossible to fulfill due to mixins and static if. They are special because they can alter the symbol table based on the contents of the symbol table. I think you could get away with defining that 'the order of declarations does not matter - except for static if and mixin which always get evaluated in lexical order'. I'm not sure how much work it'd be to make dmd behave that way. It probably wouldn't be worthwile.

I prefer: The order of declarations NEVER matters, and the above code is illegal. It's easy to implement.

The order matters for static if and version when you have else-if and/or else branches for them - it would be a problem if it didn't (especially for version, which is so dead-simple), but aside from that I agree that the order of declarations in non-local scope should never matter. - Jonathan M Davis

I'd go as far as saying that even in local scopes, local functions should be able to forward-reference other local functions. Currently, you cannot even insert forward declarations for local functions.
Sep 15 2011
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, September 15, 2011 14:59:29 Don wrote:
 On 08.09.2011 17:26, Christian Kamm wrote:
 Timon Gehr wrote:
 I am strongly in favor of disallowing any cases where mixin
 declarations
 shadow declarations that were used to compute mixin declarations in a
 scope that allows forward references.
 
 
 Any thoughts on this?

Order-of-static-evaluation problems are not limited to mixins: static if (!is(typeof(foo)) enum bar = 1; static if (!is(typeof(bar)) enum foo = 1; with the way dmd handles forward references, this can go either way depending on which static if gets evaluated first. D's wish that 'the order of declarations does not matter' is impossible to fulfill due to mixins and static if. They are special because they can alter the symbol table based on the contents of the symbol table. I think you could get away with defining that 'the order of declarations does not matter - except for static if and mixin which always get evaluated in lexical order'. I'm not sure how much work it'd be to make dmd behave that way. It probably wouldn't be worthwile.

I prefer: The order of declarations NEVER matters, and the above code is illegal. It's easy to implement.

The order matters for static if and version when you have else-if and/or else branches for them - it would be a problem if it didn't (especially for version, which is so dead-simple), but aside from that I agree that the order of declarations in non-local scope should never matter. - Jonathan M Davis
Sep 15 2011
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, September 15, 2011 20:42:21 Timon Gehr wrote:
 On 09/15/2011 06:01 PM, Jonathan M Davis wrote:
 On Thursday, September 15, 2011 14:59:29 Don wrote:
 On 08.09.2011 17:26, Christian Kamm wrote:
 Timon Gehr wrote:
 I am strongly in favor of disallowing any cases where mixin
 declarations
 shadow declarations that were used to compute mixin declarations
 in a
 scope that allows forward references.
 
 
 Any thoughts on this?

Order-of-static-evaluation problems are not limited to mixins: static if (!is(typeof(foo)) enum bar = 1; static if (!is(typeof(bar)) enum foo = 1; with the way dmd handles forward references, this can go either way depending on which static if gets evaluated first. D's wish that 'the order of declarations does not matter' is impossible to fulfill due to mixins and static if. They are special because they can alter the symbol table based on the contents of the symbol table. I think you could get away with defining that 'the order of declarations does not matter - except for static if and mixin which always get evaluated in lexical order'. I'm not sure how much work it'd be to make dmd behave that way. It probably wouldn't be worthwile.

I prefer: The order of declarations NEVER matters, and the above code is illegal. It's easy to implement.

The order matters for static if and version when you have else-if and/or else branches for them - it would be a problem if it didn't (especially for version, which is so dead-simple), but aside from that I agree that the order of declarations in non-local scope should never matter. - Jonathan M Davis

I'd go as far as saying that even in local scopes, local functions should be able to forward-reference other local functions. Currently, you cannot even insert forward declarations for local functions.

Well, I singled out local scope, because most declarations in local scope _do_ and _must_ have their order matter. The order and location of variable declarations in a function matters a great deal. Now, we may or may not want to make it possible to have local functions be able to reference each other, but aside from them, the order of declarations inside of a function matters a great deal. It's outside of that that it should never matter. - Jonathan M Davis
Sep 15 2011