www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - __ARGS__ : allow access to (stringified) arguments,

reply Timothee Cour <thelastmammoth gmail.com> writes:
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
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
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
parent Seb <seb wilzba.ch> writes:
On Thursday, 18 January 2018 at 02:55:27 UTC, rikki cattermole 
wrote:
 On 17/01/2018 11:13 PM, Timothee Cour wrote:
 [...]
__ARG_NAMES__ would be better. Otherwise, DIP please!
Yes, please! Another good use case is std.stdio.dump: https://github.com/dlang/phobos/pull/4318
Jan 17
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
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
next sibling parent Timothee Cour <thelastmammoth gmail.com> writes:
 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
main.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
prev sibling parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
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