www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Lazy template arguments?

reply "bearophile" <bearophileHUGS lycos.com> writes:
In some case I'd like a hypothetical static ternary operator 
usable on types:

alias T = (U.sizeof <= 16) ?? ushort : size_t;

That is equivalent to:

static if (U.sizeof <= 16) {
     alias T = ushort;
} else {
     alias T = size_t;
}


The syntax of a possible library implementation is acceptable:

alias T = Ternary!(U.sizeof <= 16, ushort, size_t);


But I think to implement it well in library code you need a kind 
of "lazy" for types (it means the T2 type is not computed if b is 
false):


template Ternary(bool b, T1, lazy T2) {
     static if (b)
         alias Ternary = T1;
     else
         alias Ternary = T2;
}


Are such lazy type arguments generally useful for other purposes?

Bye,
bearophile
Jan 05 2013
parent reply "comco" <void.unsigned gmail.com> writes:
On Saturday, 5 January 2013 at 10:37:31 UTC, bearophile wrote:
 In some case I'd like a hypothetical static ternary operator 
 usable on types:

 alias T = (U.sizeof <= 16) ?? ushort : size_t;

 That is equivalent to:

 static if (U.sizeof <= 16) {
     alias T = ushort;
 } else {
     alias T = size_t;
 }


 The syntax of a possible library implementation is acceptable:

 alias T = Ternary!(U.sizeof <= 16, ushort, size_t);


 But I think to implement it well in library code you need a 
 kind of "lazy" for types (it means the T2 type is not computed 
 if b is false):


 template Ternary(bool b, T1, lazy T2) {
     static if (b)
         alias Ternary = T1;
     else
         alias Ternary = T2;
 }


 Are such lazy type arguments generally useful for other 
 purposes?

 Bye,
 bearophile
Isn't the whole ct metaprogramming with types kind of functional and immutable? So there is no perceivable difference between the results using different evaluation strategies? I thought that the template instantiation is already implemented as being lazy?
Jan 13 2013
next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Sunday, 13 January 2013 at 11:15:03 UTC, comco wrote:
 On Saturday, 5 January 2013 at 10:37:31 UTC, bearophile wrote:
 In some case I'd like a hypothetical static ternary operator 
 usable on types:

 alias T = (U.sizeof <= 16) ?? ushort : size_t;

 That is equivalent to:

 static if (U.sizeof <= 16) {
    alias T = ushort;
 } else {
    alias T = size_t;
 }


 The syntax of a possible library implementation is acceptable:

 alias T = Ternary!(U.sizeof <= 16, ushort, size_t);


 But I think to implement it well in library code you need a 
 kind of "lazy" for types (it means the T2 type is not computed 
 if b is false):


 template Ternary(bool b, T1, lazy T2) {
    static if (b)
        alias Ternary = T1;
    else
        alias Ternary = T2;
 }


 Are such lazy type arguments generally useful for other 
 purposes?

 Bye,
 bearophile
Isn't the whole ct metaprogramming with types kind of functional and immutable? So there is no perceivable difference between the results using different evaluation strategies? I thought that the template instantiation is already implemented as being lazy?
It's lazy in terms of instantiation, not in terms of evaluation of args. For example, if you write: //---- lias T = Ternary!(U.sizeof <= 16, Foo!A, Foo!B); //---- Then the compiler *will* instantiate Foo!B. Bearophile: Is this proposal a pure optimization trick, or is there some functionality gains here. The only one I can think of, is if "Foo!B" would fail to compile. Is this what you are going for...? Also: //---- template Ternary(bool b, T1, lazy T2) { //---- While is only T2 lazy?
Jan 13 2013
next sibling parent "comco" <void.unsigned gmail.com> writes:
On Sunday, 13 January 2013 at 11:26:57 UTC, monarch_dodra wrote:
 Bearophile: Is this proposal a pure optimization trick, or is 
 there some functionality gains here. The only one I can think 
 of, is if "Foo!B" would fail to compile. Is this what you are 
 going for...?

 Also:
 //----
 template Ternary(bool b, T1, lazy T2) {
 //----
 While is only T2 lazy?
That was my point - and I thought that the arguments are evaluated lazily. Now, _if_ such support is added, why should we be able to pick the evaluation strategy - just make all the template arguments lazy by default - the behaviour won't change up for the most constructs, but it will be more expressive, because you'll be able to pass non-compiling arguments.
Jan 13 2013
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
monarch_dodra:

 Is this proposal a pure optimization trick, or is there some 
 functionality gains here. The only one I can think of, is if 
 "Foo!B" would fail to compile. Is this what you are going 
 for...?
It's first of all a way to implement a Ternary in library code, because in some situations instantiating a template causes an error, so the lazyness is needed to avoid those errors, and instantiate only the correct branch/argument. If this feature also reduces the compilation time a bit, then it's welcome :-) Beside implementing a Ternary, do you see other usages for such lazy template arguments?
 Also:
 //----
 template Ternary(bool b, T1, lazy T2) {
 //----
 While is only T2 lazy?
My mistake, both of those arguments are better to be lazy: template Ternary(bool b, lazy T1, lazy T2) {...} Bye, bearophile
Jan 13 2013
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
comco:

 Isn't the whole ct metaprogramming with types kind of 
 functional and immutable?
The answer is probably positive, but functional and lazy aren't exactly the same thing, from a computational point of view.
 I thought that the template instantiation is already
 implemented as being lazy?
I don't know how much. Bye, bearophile
Jan 13 2013