www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Cannot alias expression

reply "John Colvin" <john.loughran.colvin gmail.com> writes:
I suspect I'm being very dumb here, but I can't get my head 
around this:

     template B(alias A)
     {
	alias B = A;
     }
     template C(A ...)
     {
	alias C = A[0];
     }
     static assert(B!1 == 1); //fine
     static assert(C!1 == 1); //Error: cannot alias an expression 1
Oct 21 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 21 October 2013 at 12:58:55 UTC, John Colvin wrote:
 I suspect I'm being very dumb here, but I can't get my head 
 around this:

     template B(alias A)
     {
 	alias B = A;
     }
     template C(A ...)
     {
 	alias C = A[0];
     }
     static assert(B!1 == 1); //fine
     static assert(C!1 == 1); //Error: cannot alias an 
 expression 1
I think this is a good match for a gold collection of "awkward mismatch of template alias vs normal alias". I am quite surprised former template work actually, aliases are not supposed to handle expressions at all. But magic of template alias parameter turns expression into symbol and here we go.
Oct 21 2013
parent reply "simendsjo" <simendsjo gmail.com> writes:
On Monday, 21 October 2013 at 15:00:26 UTC, Dicebot wrote:
 On Monday, 21 October 2013 at 12:58:55 UTC, John Colvin wrote:
 I suspect I'm being very dumb here, but I can't get my head 
 around this:

    template B(alias A)
    {
 	alias B = A;
    }
    template C(A ...)
    {
 	alias C = A[0];
    }
    static assert(B!1 == 1); //fine
    static assert(C!1 == 1); //Error: cannot alias an 
 expression 1
I think this is a good match for a gold collection of "awkward mismatch of template alias vs normal alias". I am quite surprised former template work actually, aliases are not supposed to handle expressions at all. But magic of template alias parameter turns expression into symbol and here we go.
I didn't know the B template would work... Is this correct semantics according to the spec?
Oct 21 2013
next sibling parent "Dicebot" <public dicebot.lv> writes:
On Monday, 21 October 2013 at 16:51:02 UTC, simendsjo wrote:
 I didn't know the B template would work... Is this correct 
 semantics according to the spec?
http://dlang.org/template.html#TemplateAliasParameter "Literals can also be used as arguments to alias parameters."
Oct 21 2013
prev sibling next sibling parent "simendsjo" <simendsjo gmail.com> writes:
On Monday, 21 October 2013 at 16:51:02 UTC, simendsjo wrote:
 On Monday, 21 October 2013 at 15:00:26 UTC, Dicebot wrote:
 On Monday, 21 October 2013 at 12:58:55 UTC, John Colvin wrote:
 I suspect I'm being very dumb here, but I can't get my head 
 around this:

   template B(alias A)
   {
 	alias B = A;
   }
   template C(A ...)
   {
 	alias C = A[0];
   }
   static assert(B!1 == 1); //fine
   static assert(C!1 == 1); //Error: cannot alias an 
 expression 1
I think this is a good match for a gold collection of "awkward mismatch of template alias vs normal alias". I am quite surprised former template work actually, aliases are not supposed to handle expressions at all. But magic of template alias parameter turns expression into symbol and here we go.
I didn't know the B template would work... Is this correct semantics according to the spec?
I've used quite some T(A...), so I was used to literals not being aliasable. A bit strange that literals "is symbols" (or how I should phrase it) when using T(alias A), but not T(A...).
Oct 21 2013
prev sibling parent reply "simendsjo" <simendsjo gmail.com> writes:
On Monday, 21 October 2013 at 16:51:02 UTC, simendsjo wrote:
 On Monday, 21 October 2013 at 15:00:26 UTC, Dicebot wrote:
 On Monday, 21 October 2013 at 12:58:55 UTC, John Colvin wrote:
 I suspect I'm being very dumb here, but I can't get my head 
 around this:

   template B(alias A)
   {
 	alias B = A;
   }
   template C(A ...)
   {
 	alias C = A[0];
   }
   static assert(B!1 == 1); //fine
   static assert(C!1 == 1); //Error: cannot alias an 
 expression 1
I think this is a good match for a gold collection of "awkward mismatch of template alias vs normal alias". I am quite surprised former template work actually, aliases are not supposed to handle expressions at all. But magic of template alias parameter turns expression into symbol and here we go.
I didn't know the B template would work... Is this correct semantics according to the spec?
I've used quite some T(A...), so I was used to literals not being aliasable. A bit strange that literals "is symbols" (or how I should phrase it) when using T(alias A), but not T(A...).
Oct 21 2013
parent "Dicebot" <public dicebot.lv> writes:
On Monday, 21 October 2013 at 19:33:07 UTC, simendsjo wrote:
 I've used quite some T(A...), so I was used to literals not 
 being
 aliasable.
 A bit strange that literals "is symbols" (or how I should phrase
 it) when using T(alias A), but not T(A...).
Literals are never symbols. It is a special case for template alias parameter. But alias parameter itself it a symbol and thus can be used with normal alias. Variadic template argument list infers literal as a value, not as a template alias parameter. Values can't be used with normal aliases and thus it fails.
Oct 21 2013
prev sibling next sibling parent "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
On Monday, 21 October 2013 at 12:58:55 UTC, John Colvin wrote:
 I suspect I'm being very dumb here, but I can't get my head 
 around this:

     template B(alias A)
     {
 	alias B = A;
     }
     template C(A ...)
     {
 	alias C = A[0];
     }
     static assert(B!1 == 1); //fine
     static assert(C!1 == 1); //Error: cannot alias an 
 expression 1
I say file it as a bug. That will make for an official answer on what is correct. Could be that template B shouldn't be valid either.
Oct 21 2013
prev sibling next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 21 October 2013 at 12:58:55 UTC, John Colvin wrote:
 I suspect I'm being very dumb here, but I can't get my head 
 around this:

     template B(alias A)
     {
 	alias B = A;
     }
     template C(A ...)
     {
 	alias C = A[0];
     }
     static assert(B!1 == 1); //fine
     static assert(C!1 == 1); //Error: cannot alias an 
 expression 1
Also: struct S{} template B(alias A) { alias B = A; } template C(A ...) { alias C = A[0]; } pragma(msg, B!int); //Error: template instance B!(int) //does not match template declaration B(alias A) pragma(msg, B!S); // S pragma(msg, C!int); // int pragma(msg, C!S); // S
Oct 21 2013
next sibling parent reply "simendsjo" <simendsjo gmail.com> writes:
On Monday, 21 October 2013 at 18:42:27 UTC, John Colvin wrote:
 On Monday, 21 October 2013 at 12:58:55 UTC, John Colvin wrote:
 I suspect I'm being very dumb here, but I can't get my head 
 around this:

    template B(alias A)
    {
 	alias B = A;
    }
    template C(A ...)
    {
 	alias C = A[0];
    }
    static assert(B!1 == 1); //fine
    static assert(C!1 == 1); //Error: cannot alias an 
 expression 1
Also: struct S{} template B(alias A) { alias B = A; } template C(A ...) { alias C = A[0]; } pragma(msg, B!int); //Error: template instance B!(int) //does not match template declaration B(alias A)
Alias doesn't take primitive types. I usually add a regular B(A) template overload too. Note that when you have a alias A overload, structs uses that rather than the basic A template.
     pragma(msg, B!S); // S
     pragma(msg, C!int); // int
     pragma(msg, C!S); // S
Oct 21 2013
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 21 October 2013 at 19:14:25 UTC, simendsjo wrote:
 On Monday, 21 October 2013 at 18:42:27 UTC, John Colvin wrote:
 On Monday, 21 October 2013 at 12:58:55 UTC, John Colvin wrote:
 I suspect I'm being very dumb here, but I can't get my head 
 around this:

   template B(alias A)
   {
 	alias B = A;
   }
   template C(A ...)
   {
 	alias C = A[0];
   }
   static assert(B!1 == 1); //fine
   static assert(C!1 == 1); //Error: cannot alias an 
 expression 1
Also: struct S{} template B(alias A) { alias B = A; } template C(A ...) { alias C = A[0]; } pragma(msg, B!int); //Error: template instance B!(int) //does not match template declaration B(alias A)
Alias doesn't take primitive types.
Why on earth not?
Oct 21 2013
parent "Dicebot" <public dicebot.lv> writes:
On Monday, 21 October 2013 at 20:20:45 UTC, John Colvin wrote:
 Why on earth not?
By spec / definition. Alias is intended to only work on symbols (that is the very definition of alias). Unfortunately, template alias parameter has also extra special cases for now good reason which adds confusion.
Oct 21 2013
prev sibling parent "Dicebot" <public dicebot.lv> writes:
Please check the specification I have linked ;) It is a weird 
design but implementation currently conforms to it.
Oct 21 2013
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 10/21/2013 02:58 PM, John Colvin wrote:
 I suspect I'm being very dumb here, but I can't get my head around this:

      template B(alias A)
      {
      alias B = A;
      }
      template C(A ...)
      {
      alias C = A[0];
      }
      static assert(B!1 == 1); //fine
      static assert(C!1 == 1); //Error: cannot alias an expression 1
It is awkward design. I think it should just work. In case you needed to this for anything, the following works: template ID(alias a){ alias ID = a; } // "identity function on symbols" template B(alias A){ alias B = A; } template C(A ...){ alias C = ID!(A[0]); } static assert(B!1 == 1); // fine static assert(C!1 == 1); // fine
Oct 22 2013