Thread overview
__ARGS__ : allow access to (stringified) arguments, as C's `#arg` macro
Jan 17, 2018
Timothee Cour
Jan 18, 2018
rikki cattermole
Jan 18, 2018
Seb
Jan 19, 2018
Jacob Carlborg
Jan 19, 2018
Timothee Cour
Jan 19, 2018
Simen Kjærås
January 17, 2018
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
}

```
January 18, 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!

January 18, 2018
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
January 19, 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
January 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=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)
January 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