November 16, 2006
Don Clugston wrote:
> One problem -- it seems that if the tuple has a mix of types and instances, you can't index it.
> -------------
> struct S { int x; long y; }
> 
> template Tuple(E...)
> {
>     alias E Tuple;
> }
> 
> void main()
> {
>     int q;
> 
>     alias Tuple!(S, q) Z;
>     alias Z[0] R; // fails -- "tuple E is used as a type"
> }
> -------------

About the only thing you can do with mixed tuples is pass them as arguments to another template.

> Also, is there any way to get .tupleof to return an alias tuple?
> For example, you can't write
> alias S.tupleof[0] R;

That's because you can't have an alias to an expression. You can have a pointer to an expression, though:

	auto R = &S.tupleof[0];

> Nor (more importantly) can you pass it as an template alias parameter:
> 
> template Z(alias W) {
>     const int Z = 2;
> }
> 
> const int x = Z!((S.tupleof[0]));
> 
> (If it worked, I could write a dump!(X) which would display all the names of the members of X, with their values...).
November 16, 2006
Walter Bright wrote:
> Sean Kelly wrote:
>> Ack! Related question :-)  I assume this will work at some point?:
>>
>>   T fn( T, U )( U val )
>>   {
>>       return T.init;
>>   }
>>
>>   void main()
>>   {
>>       int i = fn!(int)( 1.0 );
>>   }
>>
>> Currently, I get:
>>
>>   test.d(9): template instance fn!(int) does not match any template declaration
>>   test.d(9): Error: template instance 'fn!(int)' is not a variable
>>   test.d(9): Error: function expected before (), not fn!(int) of type int
> 
> That's a hard one to get to work, as it has chicken-and-egg problems.

Hrm... I think that one may eventually turn out to be fairly important.  It's quite common to specify only the return type for template functions in C++.  The most obvious example being the cast functions.


Sean
November 16, 2006
Sean Kelly wrote:
> Walter Bright wrote:
>> Sean Kelly wrote:
>>> Ack! Related question :-)  I assume this will work at some point?:
>>>
>>>   T fn( T, U )( U val )
>>>   {
>>>       return T.init;
>>>   }
>>>
>>>   void main()
>>>   {
>>>       int i = fn!(int)( 1.0 );
>>>   }
>>>
>>> Currently, I get:
>>>
>>>   test.d(9): template instance fn!(int) does not match any template declaration
>>>   test.d(9): Error: template instance 'fn!(int)' is not a variable
>>>   test.d(9): Error: function expected before (), not fn!(int) of type int
>>
>> That's a hard one to get to work, as it has chicken-and-egg problems.
> 
> Hrm... I think that one may eventually turn out to be fairly important.  It's quite common to specify only the return type for template functions in C++.  The most obvious example being the cast functions.

You can use nested templates as a workaround:

template myCast(T) {
  T myCast(U)(U val) {
    return cast(T) val;
  }
}

void main() {
  int i = myCast!(int)(1.0);
}
November 16, 2006
Sean Kelly wrote:
> Walter Bright wrote:
>> Sean Kelly wrote:
>>> Ack! Related question :-)  I assume this will work at some point?:
>>>
>>>   T fn( T, U )( U val )
>>>   {
>>>       return T.init;
>>>   }
>>>
>>>   void main()
>>>   {
>>>       int i = fn!(int)( 1.0 );
>>>   }
>>>
>>> Currently, I get:
>>>
>>>   test.d(9): template instance fn!(int) does not match any template declaration
>>>   test.d(9): Error: template instance 'fn!(int)' is not a variable
>>>   test.d(9): Error: function expected before (), not fn!(int) of type int
>>
>> That's a hard one to get to work, as it has chicken-and-egg problems.
> 
> Hrm... I think that one may eventually turn out to be fairly important.  It's quite common to specify only the return type for template functions in C++.  The most obvious example being the cast functions.
> 
> 
> Sean

This works, though:

import std.stdio;

template foo(T)
{
	T foo(U)(U u)
	{
		writefln(u);
		return T.init;
	}
}

void main()
{
	int i = foo!(int)(1.5);
}


xs0
November 16, 2006
Oskar Linde wrote:
> Sean Kelly wrote:
>> Walter Bright wrote:
>>> Sean Kelly wrote:
>>>> Ack! Related question :-)  I assume this will work at some point?:
>>>>
>>>>   T fn( T, U )( U val )
>>>>   {
>>>>       return T.init;
>>>>   }
>>>>
>>>>   void main()
>>>>   {
>>>>       int i = fn!(int)( 1.0 );
>>>>   }
>>>>
>>>> Currently, I get:
>>>>
>>>>   test.d(9): template instance fn!(int) does not match any template declaration
>>>>   test.d(9): Error: template instance 'fn!(int)' is not a variable
>>>>   test.d(9): Error: function expected before (), not fn!(int) of type int
>>>
>>> That's a hard one to get to work, as it has chicken-and-egg problems.
>>
>> Hrm... I think that one may eventually turn out to be fairly important.  It's quite common to specify only the return type for template functions in C++.  The most obvious example being the cast functions.
> 
> You can use nested templates as a workaround:
> 
> template myCast(T) {
>   T myCast(U)(U val) {
>     return cast(T) val;
>   }
> }
> 
> void main() {
>   int i = myCast!(int)(1.0);
> }

Nice trick!


Sean
November 17, 2006
Oskar Linde wrote:
> Sean Kelly wrote:
> 
>> Walter Bright wrote:
>>
>>> Sean Kelly wrote:
>>>
>>>> Ack! Related question :-)  I assume this will work at some point?:
>>>>
>>>>   T fn( T, U )( U val )
>>>>   {
>>>>       return T.init;
>>>>   }
>>>>
>>>>   void main()
>>>>   {
>>>>       int i = fn!(int)( 1.0 );
>>>>   }
>>>>
>>>> Currently, I get:
>>>>
>>>>   test.d(9): template instance fn!(int) does not match any template declaration
>>>>   test.d(9): Error: template instance 'fn!(int)' is not a variable
>>>>   test.d(9): Error: function expected before (), not fn!(int) of type int
>>>
>>>
>>> That's a hard one to get to work, as it has chicken-and-egg problems.
>>
>>
>> Hrm... I think that one may eventually turn out to be fairly important.  It's quite common to specify only the return type for template functions in C++.  The most obvious example being the cast functions.
> 
> 
> You can use nested templates as a workaround:
> 
> template myCast(T) {
>   T myCast(U)(U val) {
>     return cast(T) val;
>   }
> }
> 
> void main() {
>   int i = myCast!(int)(1.0);
> }


Bummer, that doesn't seem to work inside a class member template:

class Foo {
    template myCast(T) {
        T myCast(U)(U val) {
            return cast(T) val;
        }
    }
}

void main() {
  Foo foo = new Foo;
  int i = foo.myCast!(int)(1.0);
}

-->
Error: function expected before (), not 'foo dotexp template myCast(U)'

--bb
November 17, 2006
Bill Baxter wrote:
> Oskar Linde wrote:
>> Sean Kelly wrote:
>>
>>> Walter Bright wrote:
>>>
>>>> Sean Kelly wrote:
>>>>
>>>>> Ack! Related question :-)  I assume this will work at some point?:
>>>>>
>>>>>   T fn( T, U )( U val )
>>>>>   {
>>>>>       return T.init;
>>>>>   }
>>>>>
>>>>>   void main()
>>>>>   {
>>>>>       int i = fn!(int)( 1.0 );
>>>>>   }
>>>>>
>>>>> Currently, I get:
>>>>>
>>>>>   test.d(9): template instance fn!(int) does not match any template declaration
>>>>>   test.d(9): Error: template instance 'fn!(int)' is not a variable
>>>>>   test.d(9): Error: function expected before (), not fn!(int) of type int
>>>>
>>>>
>>>> That's a hard one to get to work, as it has chicken-and-egg problems.
>>>
>>>
>>> Hrm... I think that one may eventually turn out to be fairly important.  It's quite common to specify only the return type for template functions in C++.  The most obvious example being the cast functions.
>>
>>
>> You can use nested templates as a workaround:
>>
>> template myCast(T) {
>>   T myCast(U)(U val) {
>>     return cast(T) val;
>>   }
>> }
>>
>> void main() {
>>   int i = myCast!(int)(1.0);
>> }
> 
> 
> Bummer, that doesn't seem to work inside a class member template:
> 
> class Foo {
>     template myCast(T) {
>         T myCast(U)(U val) {
>             return cast(T) val;
>         }
>     }
> }
> 
> void main() {
>   Foo foo = new Foo;
>   int i = foo.myCast!(int)(1.0);
> }
> 
> -->
> Error: function expected before (), not 'foo dotexp template myCast(U)'

Hopefully, this is just a bug.  If it can be made to work I don't see a pressing need for partial template argument evaluation.


Sean
November 18, 2006
Walter Bright wrote:
> Don Clugston wrote:
>> One problem -- it seems that if the tuple has a mix of types and instances, you can't index it.
>> -------------
>> struct S { int x; long y; }
>>
>> template Tuple(E...)
>> {
>>     alias E Tuple;
>> }
>>
>> void main()
>> {
>>     int q;
>>
>>     alias Tuple!(S, q) Z;
>>     alias Z[0] R; // fails -- "tuple E is used as a type"
>> }
>> -------------
> 
> About the only thing you can do with mixed tuples is pass them as arguments to another template.
> 
>> Also, is there any way to get .tupleof to return an alias tuple?
>> For example, you can't write
>> alias S.tupleof[0] R;
> 
> That's because you can't have an alias to an expression. You can have a pointer to an expression, though:
> 
>     auto R = &S.tupleof[0];
> 

Indexed Tuples are only expressions in syntax, not such much conceptually. What if we could also index tuple elements using template instantiation:
   alias S.tupleof!(0) R;
Then perhaps the aliasing would work with the current compiler/language rules.

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
November 18, 2006
Walter Bright wrote:
> http://www.digitalmars.com/d/tuple.html

You have the misspell "evaluatible" there.

Also, for what I see in this article, the http://www.digitalmars.com/d/template.html spec doc is a bit incomplete. No mention that Tuples can be used to "declare variables", only parameters. I also found the statement "A Tuple is not a type," a bit misleading since it seems Tuples are heading in a direction that makes them *somewhat* a type (you can declare variables with them, and even return them from functions).

Another potentially misleading statement is the:
"Tuples are static compile time entities, there is no way to dynamically change, add, or remove elements."
It's true for most tuples, but not quite so for a tuple-variable, since you can change the elements of a tuple-variable.

Speaking of tuple variables, man, that is deep stuff :P . It took me a while to grok that and to come up with a conceptualization that made sense and fit adequately. I'm thinking that tuple-variables are somewhat like anonymous structs, they are tuples of values, which happen to be Lvalues too, unlike the other expression/value templates.

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
November 19, 2006
Bruno Medeiros wrote:
> Walter Bright wrote:
>> http://www.digitalmars.com/d/tuple.html
> 
> You have the misspell "evaluatible" there.
> 
> Also, for what I see in this article, the http://www.digitalmars.com/d/template.html spec doc is a bit incomplete. No mention that Tuples can be used to "declare variables", only parameters. I also found the statement "A Tuple is not a type," a bit misleading since it seems Tuples are heading in a direction that makes them *somewhat* a type (you can declare variables with them, and even return them from functions).
> 
> Another potentially misleading statement is the:
> "Tuples are static compile time entities, there is no way to dynamically change, add, or remove elements."
> It's true for most tuples, but not quite so for a tuple-variable, since you can change the elements of a tuple-variable.
> 
> Speaking of tuple variables, man, that is deep stuff :P . It took me a while to grok that and to come up with a conceptualization that made sense and fit adequately. I'm thinking that tuple-variables are somewhat like anonymous structs, they are tuples of values, which happen to be Lvalues too, unlike the other expression/value templates.
> 

Basically, they rock. ;)