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" wroteI'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" wroteDoes 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" 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!!! :) -Steveugh! 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