Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
January 28, 2008 non-typesafe variadic lazy arguments | ||||
---|---|---|---|---|
| ||||
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 |
February 01, 2008 Re: non-typesafe variadic lazy arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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
|
February 01, 2008 Re: non-typesafe variadic lazy arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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); } |
February 04, 2008 Re: non-typesafe variadic lazy arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | "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
|
February 04, 2008 Re: non-typesafe variadic lazy arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | "Steven Schveighoffer" wrote
> "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
>
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
|
February 05, 2008 Re: non-typesafe variadic lazy arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | "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
|
Copyright © 1999-2021 by the D Language Foundation