digitalmars.D - __ARGS__ : allow access to (stringified) arguments,
- Timothee Cour (30/30) Jan 17 2018 I wrote something like that to mimic C's `#arg` preprocessor
- rikki cattermole (3/38) Jan 17 2018 __ARG_NAMES__ would be better.
- Seb (5/9) Jan 17 2018 Yes, please!
- Jacob Carlborg (12/47) Jan 19 2018 Not sure I understand this feature. Is it something like:
- Timothee Cour (16/25) Jan 19 2018 main.d:3 foo=3, bar=4 (or whatever formatting is applied given
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (27/36) Jan 19 2018 The above is trivial:
I wrote something like that to mimic C's `#arg` preprocessor (stringify argument) for debugging functions, eg: ``` // simplified here: void log(string file=__FILE__, int line=__LINE__, T) (T a){ enum arg_stringified=import(file)[line]; // more complex in practice writeln(arg_stringified, ":", a); } void main(){ log(1+3); // prints: `1+3:4` } ``` however: this slows down compilation a lot (in larger programs) and has potentially complex logic to deal with multiple arguments, and UFCS, as we need to redo the job of the parser to get access to individual elements stringified we can avoid slowing down compilation time by passing pass file,line at runtime and use readText, has the defect of not working if code was compiled and source changed at a later time. So I'd still like a solution that mimic's C's `#arg` preprocessor https://gcc.gnu.org/onlinedocs/gcc-4.0.0/cpp/Stringification.html ; it's sad that D is inferior to C in that respect. what i would like instead is __ARGS__: thus allowing: ``` void log(T...) (T a, string file=__FILE__, int line=__LINE__, string[] arg_names=__ARGS__){ writeln(file, ":", line, " ", zip(arg_names, a))); // or better formatting } ```
Jan 17 2018
On 17/01/2018 11:13 PM, Timothee Cour wrote:I wrote something like that to mimic C's `#arg` preprocessor (stringify argument) for debugging functions, eg: ``` // simplified here: void log(string file=__FILE__, int line=__LINE__, T) (T a){ enum arg_stringified=import(file)[line]; // more complex in practice writeln(arg_stringified, ":", a); } void main(){ log(1+3); // prints: `1+3:4` } ``` however: this slows down compilation a lot (in larger programs) and has potentially complex logic to deal with multiple arguments, and UFCS, as we need to redo the job of the parser to get access to individual elements stringified we can avoid slowing down compilation time by passing pass file,line at runtime and use readText, has the defect of not working if code was compiled and source changed at a later time. So I'd still like a solution that mimic's C's `#arg` preprocessor https://gcc.gnu.org/onlinedocs/gcc-4.0.0/cpp/Stringification.html ; it's sad that D is inferior to C in that respect. what i would like instead is __ARGS__: thus allowing: ``` void log(T...) (T a, string file=__FILE__, int line=__LINE__, string[] arg_names=__ARGS__){ writeln(file, ":", line, " ", zip(arg_names, a))); // or better formatting } ```__ARG_NAMES__ would be better. Otherwise, DIP please!
Jan 17 2018
On Thursday, 18 January 2018 at 02:55:27 UTC, rikki cattermole wrote:On 17/01/2018 11:13 PM, Timothee Cour wrote:Yes, please! Another good use case is std.stdio.dump: https://github.com/dlang/phobos/pull/4318[...]__ARG_NAMES__ would be better. Otherwise, DIP please!
Jan 17 2018
On 2018-01-18 00:13, Timothee Cour wrote:I wrote something like that to mimic C's `#arg` preprocessor (stringify argument) for debugging functions, eg: ``` // simplified here: void log(string file=__FILE__, int line=__LINE__, T) (T a){ enum arg_stringified=import(file)[line]; // more complex in practice writeln(arg_stringified, ":", a); } void main(){ log(1+3); // prints: `1+3:4` } ``` however: this slows down compilation a lot (in larger programs) and has potentially complex logic to deal with multiple arguments, and UFCS, as we need to redo the job of the parser to get access to individual elements stringified we can avoid slowing down compilation time by passing pass file,line at runtime and use readText, has the defect of not working if code was compiled and source changed at a later time. So I'd still like a solution that mimic's C's `#arg` preprocessor https://gcc.gnu.org/onlinedocs/gcc-4.0.0/cpp/Stringification.html ; it's sad that D is inferior to C in that respect. what i would like instead is __ARGS__: thus allowing: ``` void log(T...) (T a, string file=__FILE__, int line=__LINE__, string[] arg_names=__ARGS__){ writeln(file, ":", line, " ", zip(arg_names, a))); // or better formatting } ```Not sure I understand this feature. Is it something like: auto foo = 3; auto bar = 4; log(foo, bar); Would print? main.d:3 foo=3 main.d:3 bar=4 If that's the case then this seems like yet another hack because we don't have AST macros. -- /Jacob Carlborg
Jan 19 2018
Not sure I understand this feature. Is it something like: auto foo = 3; auto bar = 4; log(foo, bar); Would print? main.d:3 foo=3 main.d:3 bar=4main.d:3 foo=3, bar=4 (or whatever formatting is applied given supplied stringiified arguments, that's irrelevant as it can be customized inside user code)If that's the case then this seems like yet another hack because we don't have AST macros.I predicted you'd mention AST macros. While I agree AST macros would solve this and other problems, the likelihood of them appearing in D in the near future is slim. My proposal is pragmatic and can be implemented with a short PR in the near future, if people agree on this change. If/when AST macros come to D, we'd still be able to use them for that purpose. Currently there is *zero* good workaround: * either calling code is ugly (https://github.com/dlang/phobos/pull/4318) * or compile time is slowed down a lot (as I showed in my original post, via import(__FILE__)[__LINE__] + redoing the work the compiler already did) This proposal is simple to implement, useful, and exists in other languages (C++ and many others)
Jan 19 2018
On Friday, 19 January 2018 at 08:51:00 UTC, Jacob Carlborg wrote:Not sure I understand this feature. Is it something like: auto foo = 3; auto bar = 4; log(foo, bar); Would print? main.d:3 foo=3 main.d:3 bar=4 If that's the case then this seems like yet another hack because we don't have AST macros.The above is trivial: template log(Args...) { auto log(string file = __FILE__, int line = __LINE__)() { import std.stdio; static foreach (arg; Args) { writeln(file, ":", line, " ", arg.stringof, "=", arg); } } } unittest { int foo = 3; int bar = 4; log!(foo, bar); } What's hard is getting expressions as text: unittest { int foo = 3; int bar = 4; // Should print 'main.d:5 foo+bar=7' // but fails to compile with 'variable foo cannot be read at compile time' log!(foo + bar); } Actually, if we could alias expressions, this should Just Workâ˘. -- Simen
Jan 19 2018