www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Variadic Templates or functions with Lazy Evalutaion

reply convert <convert somewhere.com> writes:
I am trying to write a log function that can take a variable number of
arguments and does lazy evaluation on each of them.

-------------
void log(A...) (int level ,lazy A args)
{
    if(level > 1) Stdout(args).newline();
}

log(2, "Hello");

-----------

Produces:

test2.d(22): template instance test2.log!(char[6u]) error instantiating
test2.d(22): Error: functions cannot return static array char[6u]

And

void log(int level ,lazy ...)

produces:

test2.d(15): basic type expected, not ...

Should any of these work?
Aug 14 2007
next sibling parent Daniel919 <Daniel919 web.de> writes:
void test(T)(lazy T arg)
{
	writefln(arg);
}
test("abc");


is converted to:


void test(string delegate() arg)
{
	writefln(arg);
}
test({return "abc"});


So we have:
string delegate() arg = {return "abc"};

And this is related to bug #1371:

//string delegate() dg = { return "dg"; };
//Error: functions cannot return static array invariant char[2u]

string delegate() dg = delegate string() { return "dg"; }; //OK
auto dg = { return "dg".dup; }; //OK
string fn() { return "fn"; }; //OK




However this is working:
void test(T)(lazy T arg)
{
	writefln(arg);
}
test("abc".dup);



For simple logging you could also use this:
void log(args...)() {
	if (args[0] > 1)
		writefln(args[1..$]);
}
log!(2, "abc", "def")();

Remember that you can't use runtime functions/data then:
log!(2, runtimeprocessingfunction("abc"));
//Error: cannot evaluate runtimeprocessingfunction("abc") at compile time

log!(2, compiletimefunction("abc")); //OK


Best regards,
Daniel
Aug 14 2007
prev sibling parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
convert wrote:
 I am trying to write a log function that can take a variable number of
arguments and does lazy evaluation on each of them.
 
 -------------
 void log(A...) (int level ,lazy A args)
 {
     if(level > 1) Stdout(args).newline();
 }
 
 log(2, "Hello");
 
 -----------
 
 Produces:
 
 test2.d(22): template instance test2.log!(char[6u]) error instantiating
 test2.d(22): Error: functions cannot return static array char[6u]

In this case, the problem is that string literals are always static/fixed-length arrays, which cannot be returned from functions -- and lazy parameters are "on the fly" wrapped as delegate functions. Ie, the parameter 'lazy int' is typed the same as 'int delegate()'. It will work as written if you pass a full-slice of the literal -- or if the value is in a dynamic/variable-length array to begin with. log(2, "Hello"[]); This isn't so bad unless you intend to have several literal strings in a call to log... then it gets a little awkward looking. log(2, "Hello"[], "from"[], "D"[]);
 And
 
 void log(int level ,lazy ...)
 
 produces:
 
 test2.d(15): basic type expected, not ...
 
 Should any of these work?
 

This will not work because of the way (as I mentioned earlier) lazy parameters are re-written as delegates. A function must have a formal return type. -- Chris Nicholson-Sauls
Aug 14 2007