www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - No mixin scope for string mixins. Is that an oversight?

reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
Template mixins can take scope names to resolve name conflicts:

   http://dlang.org/template-mixin.html

import std.stdio;

template Templ()
{
     int i;
}

void main()
{
     mixin Templ!();
     mixin Templ!();

     writeln(i);
     /* Error: deneme.main.Templ!().i at deneme.d(149327)
      * conflicts with deneme.main.Templ!().i at
      * deneme.d(149327) */
}

The solution is to use mixin identifiers:

     mixin Templ!() A;
     mixin Templ!() B;

The code compiles but of course one must specify which 'i' to use:

     writeln(A.i);

The same feature does not exist for string mixins:

   http://dlang.org/mixin.html

Is there a reason for the omission? Is there an enhancement request for it?

However, the workaround is surprisingly trivial. First, the problem:

import std.stdio;

void main()
{
     mixin ("int i;");
     mixin ("int i;");

     writeln(i);
     /* Error: declaration deneme.main.i is already defined */
}

The solution:

import std.stdio;

template TemplateMixinize(string Str)
{
     mixin (Str);
}

void main()
{
     mixin TemplateMixinize!("int i;") A;
     mixin TemplateMixinize!("int i;") B;

     writeln(A.i);
}

Does TemplateMixinize :p already exist in Phobos?

Ali
Oct 29 2013
parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 29 October 2013 at 23:16:46 UTC, Ali Çehreli wrote:
 Template mixins can take scope names to resolve name conflicts:

   http://dlang.org/template-mixin.html

 import std.stdio;

 template Templ()
 {
     int i;
 }

 void main()
 {
     mixin Templ!();
     mixin Templ!();

     writeln(i);
     /* Error: deneme.main.Templ!().i at deneme.d(149327)
      * conflicts with deneme.main.Templ!().i at
      * deneme.d(149327) */
 }

 The solution is to use mixin identifiers:

     mixin Templ!() A;
     mixin Templ!() B;

 The code compiles but of course one must specify which 'i' to 
 use:

     writeln(A.i);

 The same feature does not exist for string mixins:

   http://dlang.org/mixin.html

 Is there a reason for the omission? Is there an enhancement 
 request for it?

 However, the workaround is surprisingly trivial. First, the 
 problem:

 import std.stdio;

 void main()
 {
     mixin ("int i;");
     mixin ("int i;");

     writeln(i);
     /* Error: declaration deneme.main.i is already defined */
 }

 The solution:

 import std.stdio;

 template TemplateMixinize(string Str)
 {
     mixin (Str);
 }

 void main()
 {
     mixin TemplateMixinize!("int i;") A;
     mixin TemplateMixinize!("int i;") B;

     writeln(A.i);
 }

 Does TemplateMixinize :p already exist in Phobos?

 Ali
This is a good workaround that I commonly use. Should be in phobos. However, the real problem is the opposite one: To use a mixin template without it having it's own scope. Having to resort to string mixins to add constructors or do proper overloads is ugly and can cause a code duplication (one mixin template and one string template) which is exactly what mixins are for avoiding. Perhaps we could have: mixin template MixinTemplate(...){...} scope mixin MixinTemplate!(...); or maybe scope mixin MixinTemplate(...){...} mixin MixinTemplate!(...);
Oct 30 2013