digitalmars.D.bugs - [Issue 1839] New: Give D a modern varargs system that allows forwarding
- d-bugmail puremagic.com (34/34) Feb 14 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
- Janice Caron (11/13) Feb 14 2008 Will this not work?
- d-bugmail puremagic.com (6/6) Feb 14 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
- d-bugmail puremagic.com (5/5) Feb 14 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
- d-bugmail puremagic.com (11/11) Feb 15 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
- Lars Ivar Igesund (3/12) Feb 15 2008 If there is absolutely no bloat when using such a template, only then wi...
- d-bugmail puremagic.com (7/7) Feb 15 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
- d-bugmail puremagic.com (17/23) Feb 15 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
- d-bugmail puremagic.com (11/11) Feb 15 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
- d-bugmail puremagic.com (29/29) Feb 15 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
- d-bugmail puremagic.com (21/21) Feb 15 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
- d-bugmail puremagic.com (9/41) Feb 15 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
- Jarrett Billingsley (13/52) Feb 15 2008 I'll suggest it again: given a typesafe variadic function whose variadi...
- Lars Ivar Igesund (2/72) Feb 15 2008 Only that that would move Variant into the runtime which is unfortunate.
- d-bugmail puremagic.com (39/44) Feb 15 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
- d-bugmail puremagic.com (17/40) Feb 15 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
- d-bugmail puremagic.com (10/22) Feb 15 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1839
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 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 ...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 "..."-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"..."-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 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=1839If (...) 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 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 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 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=1839I 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/...Only that that would move Variant into the runtime which is unfortunate.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
http://d.puremagic.com/issues/show_bug.cgi?id=1839Ok, 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 |(e) want to have a callback/signal-slot/observer/notification system capable of using varargs functions as callbacks.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 issueThere 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 |ASSIGNEDOh. I planned to do so myself, but forgot while I was writing the post. Andrei --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