Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
January 17, 2018 __ARGS__ : allow access to (stringified) arguments, as C's `#arg` macro | ||||
---|---|---|---|---|
| ||||
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 Re: __ARGS__ : allow access to (stringified) arguments, as C's `#arg` macro | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timothee Cour | 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 Re: __ARGS__ : allow access to (stringified) arguments, as C's `#arg` macro | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | 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 Re: __ARGS__ : allow access to (stringified) arguments, as C's `#arg` macro | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timothee Cour | 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 Re: __ARGS__ : allow access to (stringified) arguments, as C's `#arg` macro | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | > 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 Re: __ARGS__ : allow access to (stringified) arguments, as C's `#arg` macro | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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
|
Copyright © 1999-2021 by the D Language Foundation