www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Eponymous templates ambiguity

reply "andrea9940" <no mail.plz> writes:
Hello D world, I have just started using templates and mixins to 
generate some boilerplate code and I have found a little 
ambiguity:

This code compiles fine:

private template genTypes()
{
	string eval() { ... }
	const(char[]) genTypes = eval();
}
mixin(genTypes!());  // Working

But this does not, why ?

private template genTypes()
{
	string eval() { ... }
	string genTypes = eval();
}
mixin(genTypes!()); // Error: variable genTypes cannot be read at 
compile time

I would expect both version to work.

( complete code at http://pastebin.com/FhmrgmZZ )
Aug 03 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
andrea9940:

 ( complete code at http://pastebin.com/FhmrgmZZ )
Simpler code: import std.stdio; import std.typecons; private immutable extensionTable = [ ["WGL_ARB_make_current_read", "void function(int, int, int)", "wglMakeContextCurrentARB", "void function()", "wglGetCurrentReadDCARB"], ["WGL_ARB_pixel_format_float"], ["WGL_ARB_create_context", "void function(int, int, int)", "wglCreateContextAttribsARB"], ]; string eval() { string code; foreach (const array; extensionTable) for (uint index = 1; index < array.length; index += 2) code ~= "alias nothrow " ~ array[index] ~ " da_" ~ array[index + 1] ~ ";"; return code; } mixin(eval); void main() { assert(is(da_wglCreateContextAttribsARB)); } Bye, bearophile
Aug 03 2013
prev sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Saturday, 3 August 2013 at 11:27:30 UTC, andrea9940 wrote:
 Hello D world, I have just started using templates and mixins 
 to generate some boilerplate code and I have found a little 
 ambiguity:

 This code compiles fine:

 private template genTypes()
 {
 	string eval() { ... }
 	const(char[]) genTypes = eval();
 }
 mixin(genTypes!());  // Working

 But this does not, why ?

 private template genTypes()
 {
 	string eval() { ... }
 	string genTypes = eval();
 }
 mixin(genTypes!()); // Error: variable genTypes cannot be read 
 at compile time

 I would expect both version to work.

 ( complete code at http://pastebin.com/FhmrgmZZ )
It is probably because you did not write what you meant. First, take notice that: const(char[]) //(1) is different from const(char)[] //(2) 1 is "full const", which means the compiler, since it is smart enough, is able to say "hey, I can evaluate this variable at compile time". In 2, however, while the "payload" of the array is const, the array itself isn't. For example, you'll notice this is perfectly legal: private template genTypes() { string eval() { return "hello"; } string genTypes = eval(); } void main() { genTypes!() = "world"; } As you can see, genTypes just resolves to a GLOBAL string, and not to a manifest constant string. Because of this, mixin in genTypes is not possible. What you probably meant to write was: private template genTypes() { string eval() { ... } enum string genTypes = eval(); //or just enum genTypes = eval(); } This means genTypes will resolve statically to the string returned by eval, and you can mix that in. If you use "const" or "immutable" instead of "enum", then the compiler will also generate a reference-able string for genTypes, which you may or may not want. Hint, if in doubt, use enum, that's what phobos does 100% of the time.
Aug 03 2013
parent "andrea9940" <no mail.plz> writes:
Thanks to both of you !
Aug 03 2013