digitalmars.D.learn - non-typesafe variadic lazy arguments
- Steven Schveighoffer (30/30) Jan 28 2008 I'm sure this has been asked before, but I can't remember the answer.
- Steven Schveighoffer (3/33) Feb 01 2008 Does nobody have any insight on this? :(
- Regan Heath (23/23) Feb 01 2008 Does this help:
- Steven Schveighoffer (12/34) Feb 04 2008 I definitely learned something here, but unfortunately, this doesn't sol...
- Steven Schveighoffer (9/49) Feb 04 2008 However, this does work:
- Steven Schveighoffer (11/19) Feb 05 2008 ugh! it almost works :) The issue is with lazy args and string/array
I'm sure this has been asked before, but I can't remember the answer.
How does one create a function that takes non-typed variadic arguments?
Essentially, what I want is for this to work:
void f(lazy ...);
The current spec allows for typed variadic lazy functions i.e.:
void f(char[] delegate()[] dg ...); // every arg has to be a char[]
But if I want any type to be passed in, there doesn't seem to be a way to do
it, as there is no builtin type that any type can be casted to implicitly
(or is there?).
If I want to evaluate the variadic args lazily, I can use a level of
indirection:
char[] evalOnCondition(bool condition, lazy char[] result)
{
if(condition) writefln(result);
}
variadicF(char[] buffer, ...){...}
char[400] buf;
evalOnCondition(loops==5, variadicF(buf, "inloop", 5));
But what I really want to do is intercept the variadic function call. I
want to provide a function that allows you to call evalOnCondition and
variadicF without a buffer and without allocating it from the heap:
variadicEvalOnCondition(bool condition, lazy ...)
{
char[400] buf;
if(condition)
writefln(variadicF(buf, _argptr, _arguments)); // doesn't eval ... until
here
}
Any ideas how this can be done?
-Steve
Jan 28 2008
Does nobody have any insight on this? :(
-Steve
"Steven Schveighoffer" wrote
I'm sure this has been asked before, but I can't remember the answer.
How does one create a function that takes non-typed variadic arguments?
Essentially, what I want is for this to work:
void f(lazy ...);
The current spec allows for typed variadic lazy functions i.e.:
void f(char[] delegate()[] dg ...); // every arg has to be a char[]
But if I want any type to be passed in, there doesn't seem to be a way to
do it, as there is no builtin type that any type can be casted to
implicitly (or is there?).
If I want to evaluate the variadic args lazily, I can use a level of
indirection:
char[] evalOnCondition(bool condition, lazy char[] result)
{
if(condition) writefln(result);
}
variadicF(char[] buffer, ...){...}
char[400] buf;
evalOnCondition(loops==5, variadicF(buf, "inloop", 5));
But what I really want to do is intercept the variadic function call. I
want to provide a function that allows you to call evalOnCondition and
variadicF without a buffer and without allocating it from the heap:
variadicEvalOnCondition(bool condition, lazy ...)
{
char[400] buf;
if(condition)
writefln(variadicF(buf, _argptr, _arguments)); // doesn't eval ...
until here
}
Any ideas how this can be done?
-Steve
Feb 01 2008
Does this help:
module lazy_any;
import std.thread;
import std.stdio;
import std.c.time;
import std.c.string;
import std.string;
void call(R, U...)(bool condition, R delegate(U) dg, U args)
{
if (condition)
writefln(dg(args));
}
void main(string[] args)
{
string bob(int i, string s, float f)
{
return format("%s, %s, %s", i, s, f);
}
call(true, &bob, 1, "test1".idup, 5.2f);
call(false, &bob, 2, "test2".idup, 6.3f);
call(true, &bob, 3, "test3".idup, 7.4f);
}
Feb 01 2008
"Regan Heath" wrote
Does this help:
module lazy_any;
import std.thread;
import std.stdio;
import std.c.time;
import std.c.string;
import std.string;
void call(R, U...)(bool condition, R delegate(U) dg, U args)
{
if (condition)
writefln(dg(args));
}
void main(string[] args)
{
string bob(int i, string s, float f)
{
return format("%s, %s, %s", i, s, f);
}
call(true, &bob, 1, "test1".idup, 5.2f);
call(false, &bob, 2, "test2".idup, 6.3f);
call(true, &bob, 3, "test3".idup, 7.4f);
}
I definitely learned something here, but unfortunately, this doesn't solve
the problem. What I want is for the tuple to be converted to delegates just
like lazy converts arguments to delegates.
To demonstrate my issue, I think this would still evaluate f:
string f(string x, string y)
{
return x ~ y;
}
call(false, &bob, 1, f("test", "1"), 5.2f);
What I want is a way so that f("test", "1") is not evaluated unless needed.
-Steve
Feb 04 2008
"Steven Schveighoffer" wrote"Regan Heath" wroteHowever, this does work: void call(R, U...)(bool condition, R delegate(U) dg, lazy U args) { if (condition) writefln(dg(args)); } Thanks for the help Regan!!! :) -SteveDoes this help: module lazy_any; import std.thread; import std.stdio; import std.c.time; import std.c.string; import std.string; void call(R, U...)(bool condition, R delegate(U) dg, U args) { if (condition) writefln(dg(args)); } void main(string[] args) { string bob(int i, string s, float f) { return format("%s, %s, %s", i, s, f); } call(true, &bob, 1, "test1".idup, 5.2f); call(false, &bob, 2, "test2".idup, 6.3f); call(true, &bob, 3, "test3".idup, 7.4f); }I definitely learned something here, but unfortunately, this doesn't solve the problem. What I want is for the tuple to be converted to delegates just like lazy converts arguments to delegates. To demonstrate my issue, I think this would still evaluate f: string f(string x, string y) { return x ~ y; } call(false, &bob, 1, f("test", "1"), 5.2f); What I want is a way so that f("test", "1") is not evaluated unless needed. -Steve
Feb 04 2008
"Steven Schveighoffer" wrote
However, this does work:
void call(R, U...)(bool condition, R delegate(U) dg, lazy U args)
{
if (condition)
writefln(dg(args));
}
Thanks for the help Regan!!! :)
-Steve
ugh! it almost works :) The issue is with lazy args and string/array
literals.
If you do this:
call(true, &bob, "hello");
The compiler complains because it can't create a delegate function that
returns a char[5u]. Functions cannot return a static array, so this seems
rather silly (i.e. if you are lazily evaluating a string constant, there is
no penalty for returning a char[] instead of a char[5u]). I'm going to file
it as a bug, but if this gets fixed, everything will be good!
-Steve
Feb 05 2008








"Steven Schveighoffer" <schveiguy yahoo.com>