digitalmars.D.bugs - [Issue 1839] New: Give D a modern varargs system that allows forwarding
- d-bugmail puremagic.com Feb 14 2008
- "Janice Caron" <caron800 googlemail.com> Feb 14 2008
- d-bugmail puremagic.com Feb 14 2008
- d-bugmail puremagic.com Feb 14 2008
- d-bugmail puremagic.com Feb 15 2008
- Lars Ivar Igesund <larsivar igesund.net> Feb 15 2008
- d-bugmail puremagic.com Feb 15 2008
- d-bugmail puremagic.com Feb 15 2008
- d-bugmail puremagic.com Feb 15 2008
- d-bugmail puremagic.com Feb 15 2008
- d-bugmail puremagic.com Feb 15 2008
- d-bugmail puremagic.com Feb 15 2008
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Feb 15 2008
- Lars Ivar Igesund <larsivar igesund.net> Feb 15 2008
- d-bugmail puremagic.com Feb 15 2008
- d-bugmail puremagic.com Feb 15 2008
- d-bugmail puremagic.com Feb 15 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 Summary: Give D a modern varargs system that allows forwarding Product: D Version: 2.010 Platform: PC OS/Version: Windows Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: bugzilla digitalmars.com ReportedBy: wbaxter gmail.com Given function void A(...) { ... } It should be possible to write a function wrapsA of this sort: void wrapsA(...) { pre_call(); A(...); // or whatever syntax you want for forwarding the varargs. post_call(); } That D -- a supposedly modern, easy-to-use languages -- can't do this conceptually simple thing is sad. The whole point of procedural programming is that code is encapsulated into reusable blocks. Not being able to forward varargs means that a big chunk of that reusability is lost any time you write a varargs function. The workaround is to write every varargs function in two flavors, one thats got (...) args, and one that's got (_argptr,_arguments) args. But if the solution is so mechanical and straightforward then why can't the compiler at just do that for us? I'm not saying that's the right way to implement vararg forwarding, but barring a more elegant solution, that sounds like at least a plausible solution. --
Feb 14 2008
On 15/02/2008, d-bugmail puremagic.com <d-bugmail puremagic.com> wrote:That D -- a supposedly modern, easy-to-use languages -- can't do this conceptually simple thing is sad.
Will this not work? import std.traits; ReturnType!(f) wraps(alias f)(ParameterTypeTuple!(f) t) { pre_call(); ReturnType!(f) x = f(t); post_call(); return x; } wrap!(A)(params);
Feb 14 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 ------- Comment #2 from wbaxter gmail.com 2008-02-15 01:56 ------- Sometimes you can't / don't want to use a template. If templates were an answer then we wouldn't need the regular vararg functions to begin with. --
Feb 14 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 ------- Comment #3 from wbaxter gmail.com 2008-02-15 01:58 ------- ...and what is the parameter type tuple of a varargs function? I suspect that probably doesn't work actually. --
Feb 14 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 andrei metalanguage.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |INVALID ------- Comment #4 from andrei metalanguage.com 2008-02-15 02:36 ------- "..."-style varargs predate template varargs and have a number of disadvantages compared to them, so it is likely they will get deprecated in favor of templates and macros. --
Feb 15 2008
d-bugmail puremagic.com wrote:http://d.puremagic.com/issues/show_bug.cgi?id=1839
------- Comment #4 from andrei metalanguage.com 2008-02-15 02:36 ------- "..."-style varargs predate template varargs and have a number of disadvantages compared to them, so it is likely they will get deprecated in favor of templates and macros. --
If there is absolutely no bloat when using such a template, only then will it be acceptible to remove a runtime alternative.
Feb 15 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 ------- Comment #5 from wbaxter gmail.com 2008-02-15 02:39 ------- If (...) functions go away, then yes, this bug report becomes pointless. The template versions of forwarding will do the trick. But how do I create a delegate that takes an arbitrary list of arbitrary arguments using templates? --
Feb 15 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 ------- Comment #6 from andrei metalanguage.com 2008-02-15 02:47 ------- (In reply to comment #5)If (...) functions go away, then yes, this bug report becomes pointless. The template versions of forwarding will do the trick. But how do I create a delegate that takes an arbitrary list of arbitrary arguments using templates?
import std.stdio; void before() {} void after() {} void forward(F, T...)(F fun, T args) { before(); scope(exit) after(); fun(args); } void main() { forward((int a) { writeln(a + 40); }, 2); } --
Feb 15 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 ------- Comment #7 from wbaxter gmail.com 2008-02-15 02:58 ------- I mean this: ---- void delegate(...) callback = &fn; ... callback("hi", 10, "mom"); ---- Does your snippet of code show how to do that? If so, I'm not seeing the connection, so please explain again. --
Feb 15 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 ------- Comment #8 from andrei metalanguage.com 2008-02-15 03:35 ------- I misunderstood your initial code sample. In fact that's a simpler problem: import std.stdio; void before() {} void after() {} void fn(...) { foreach (i; 0 .. _arguments.length) { _arguments[i].print; } if (_arguments[0] == typeid(int)) { int j = *cast(int *)_argptr; writeln(j); } } void wrapsFn(T...)(T args) { before(); scope(exit) after(); fn(args); } void main() { wrapsFn(2, 42, "a"); } --
Feb 15 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 ------- Comment #9 from aarti interia.pl 2008-02-15 04:16 ------- Isn't it that variable arguments templates have its own problems also? Executable size will increase very quickly for different types/combinations of parameters. AFAIK it will happen especially when template body will be very big. Sure you can split big template into smaller, but it means also that size of program will heavily depend on coding style of programmer. Or is it possible to optimize such a big template automagically? But I think that, if variable argument templates are not able to be instant replacement (considering e.g. size of executable), variable arguments functions should stay... When they would stay a few simple fixes would probably enhance current situation in order of magnitude. 1. Defining struct, which will keep typeinfo pointer and data pointer e.g. struct Arg {TypeInfo type; void* ptr;} 2. Then variable argument functions could be declared like other type safe variadic argument functions in D: void func(Arg[] param...) {} ...and the problem with passing arguments would be solved... (also ugly local variables (=hacks): _argptr, _arguments could disappear). --
Feb 15 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 ------- Comment #10 from wbaxter gmail.com 2008-02-15 04:58 ------- (In reply to comment #8)I misunderstood your initial code sample. In fact that's a simpler problem: import std.stdio; void before() {} void after() {} void fn(...) { foreach (i; 0 .. _arguments.length) { _arguments[i].print; } if (_arguments[0] == typeid(int)) { int j = *cast(int *)_argptr; writeln(j); } } void wrapsFn(T...)(T args) { before(); scope(exit) after(); fn(args); } void main() { wrapsFn(2, 42, "a"); }
Ok, but it's no longer a function. I can't do with wrapFn the same things I can do with a regular function, namely taking it's address and passing that around or calling through it later. If there were a simple and efficient way to convert the wrapsFn template into a function pointer then I'd be satisfied with that solution. --
Feb 15 2008
<d-bugmail puremagic.com> wrote in message news:bug-1839-3 http.d.puremagic.com/issues/...http://d.puremagic.com/issues/show_bug.cgi?id=1839 Summary: Give D a modern varargs system that allows forwarding Product: D Version: 2.010 Platform: PC OS/Version: Windows Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: bugzilla digitalmars.com ReportedBy: wbaxter gmail.com Given function void A(...) { ... } It should be possible to write a function wrapsA of this sort: void wrapsA(...) { pre_call(); A(...); // or whatever syntax you want for forwarding the varargs. post_call(); } That D -- a supposedly modern, easy-to-use languages -- can't do this conceptually simple thing is sad. The whole point of procedural programming is that code is encapsulated into reusable blocks. Not being able to forward varargs means that a big chunk of that reusability is lost any time you write a varargs function. The workaround is to write every varargs function in two flavors, one thats got (...) args, and one that's got (_argptr,_arguments) args. But if the solution is so mechanical and straightforward then why can't the compiler at just do that for us? I'm not saying that's the right way to implement vararg forwarding, but barring a more elegant solution, that sounds like at least a plausible solution.
I'll suggest it again: given a typesafe variadic function whose variadic parameter's array element type is a struct: void A(Variant[] args...) calling that function: A(1, 2, "hi") should be sugar for: A(Variant(1), Variant(2), Variant("hi")) This alone would obviate the need for ... style vararg functions. A Variant array is far, far more useful than the platform-dependent hard-to-use inflexible _arguments/_argptr crap. And at the same time, solves the "OMG template bloat!!" problem.
Feb 15 2008
Jarrett Billingsley wrote:<d-bugmail puremagic.com> wrote in message news:bug-1839-3 http.d.puremagic.com/issues/...http://d.puremagic.com/issues/show_bug.cgi?id=1839 Summary: Give D a modern varargs system that allows forwarding Product: D Version: 2.010 Platform: PC OS/Version: Windows Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: bugzilla digitalmars.com ReportedBy: wbaxter gmail.com Given function void A(...) { ... } It should be possible to write a function wrapsA of this sort: void wrapsA(...) { pre_call(); A(...); // or whatever syntax you want for forwarding the varargs. post_call(); } That D -- a supposedly modern, easy-to-use languages -- can't do this conceptually simple thing is sad. The whole point of procedural programming is that code is encapsulated into reusable blocks. Not being able to forward varargs means that a big chunk of that reusability is lost any time you write a varargs function. The workaround is to write every varargs function in two flavors, one thats got (...) args, and one that's got (_argptr,_arguments) args. But if the solution is so mechanical and straightforward then why can't the compiler at just do that for us? I'm not saying that's the right way to implement vararg forwarding, but barring a more elegant solution, that sounds like at least a plausible solution.
I'll suggest it again: given a typesafe variadic function whose variadic parameter's array element type is a struct: void A(Variant[] args...) calling that function: A(1, 2, "hi") should be sugar for: A(Variant(1), Variant(2), Variant("hi")) This alone would obviate the need for ... style vararg functions. A Variant array is far, far more useful than the platform-dependent hard-to-use inflexible _arguments/_argptr crap. And at the same time, solves the "OMG template bloat!!" problem.
Only that that would move Variant into the runtime which is unfortunate.
Feb 15 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 ------- Comment #13 from andrei metalanguage.com 2008-02-15 16:32 ------- (In reply to comment #10)Ok, but it's no longer a function. I can't do with wrapFn the same things I can do with a regular function, namely taking it's address and passing that around or calling through it later. If there were a simple and efficient way to convert the wrapsFn template into a function pointer then I'd be satisfied with that solution.
I understand, and that's a good point. There can't be a conversion from that template to a delegate(...) without breaking type safety. Here are some other thoughts. 1. The feature you are suggesting offers diminishing returns. It will help people who: (a) write a ton of (...) functions so they hate the forwarding idea (b) don't like macros that would partially automate (a) (c) call a ton of (...) functions and work so any syntactical burden would be unacceptable (d) are in an environment such that template bloat is an issue There are things that D can't do today, and things that it can do in clunky ways that are encountered more often than the above. I think it's best we focus on those first. 2. That being said, I've tried to convice Walter of the utility of the "return goto" statement, which replaces one function entirely with another. That would be extremely cheap forwarding for a variety of cases, and would make tail recursion and mutual recursion obvious and documentable. If that feature were in, you'd have half of your needed feature: void foo(...) { ... } void callfoo(...) { before(); return goto foo; } You can't do an "after" action because the return goto statement effectively "execs" foo, and as such callfoo's frame ceases existence. This statement is easy to typecheck and generates good modular code, but it has certain limitations (e.g. callfoo cannot have scope() statements, locals with destructors etc.) So this feature would cover some things, and yours would cover some overlapping things. I'm not sure whether either or both have critical mass. Andrei --
Feb 15 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 wbaxter gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Resolution|INVALID | ------- Comment #14 from wbaxter gmail.com 2008-02-15 17:04 ------- (In reply to comment #13)(In reply to comment #10)Ok, but it's no longer a function. I can't do with wrapFn the same things I can do with a regular function, namely taking it's address and passing that around or calling through it later. If there were a simple and efficient way to convert the wrapsFn template into a function pointer then I'd be satisfied with that solution.
I understand, and that's a good point. There can't be a conversion from that template to a delegate(...) without breaking type safety. Here are some other thoughts. 1. The feature you are suggesting offers diminishing returns. It will help people who: (a) write a ton of (...) functions so they hate the forwarding idea (b) don't like macros that would partially automate (a) (c) call a ton of (...) functions and work so any syntactical burden would be unacceptable (d) are in an environment such that template bloat is an issue
(e) want to have a callback/signal-slot/observer/notification system capable of using varargs functions as callbacks.There are things that D can't do today, and things that it can do in clunky ways that are encountered more often than the above. I think it's best we focus on those first.
Agreed. I certainly didn't mean to imply by filing this that I thought this problem should be prioritized over other pressing issues. But it's something that I've long found annoying and seen discussed at various time, and yet there didn't seem to be a bug/enh filed for it yet. But it seems in conclusion that you agree with me that this should not be marked "resolved invalid". --
Feb 15 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1839 andrei metalanguage.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|REOPENED |ASSIGNED ------- Comment #15 from andrei metalanguage.com 2008-02-15 17:33 ------- (In reply to comment #14)(In reply to comment #13)There are things that D can't do today, and things that it can do in clunky ways that are encountered more often than the above. I think it's best we focus on those first.
Agreed. I certainly didn't mean to imply by filing this that I thought this problem should be prioritized over other pressing issues. But it's something that I've long found annoying and seen discussed at various time, and yet there didn't seem to be a bug/enh filed for it yet. But it seems in conclusion that you agree with me that this should not be marked "resolved invalid".
Oh. I planned to do so myself, but forgot while I was writing the post. Andrei --
Feb 15 2008









"Janice Caron" <caron800 googlemail.com> 