Thread overview | ||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 01, 2013 feature request: __ARGS__ for logging (cf __FILE__, __LINE__, __FUNC___) | ||||
---|---|---|---|---|
| ||||
One of the rare features I miss in C/C++ is stringification macro using "#x": --- #include ... #define DEBUG(x) disp_val(#x,x) template<typename T> void disp_val(const char*name, const T& x) {std::cout << name << "=" << x;} int main(){ DEBUG(1+2); //will print 1+2=3 (and we can add line, file and func info) ASSERT(1+2==4); //can also be defined such that it'll print 1+2==4 failed... } --- In D, we have built-in assert message that'll print the failing expression "1+2==4 failed" in case of failure but that's about it: no further processing can be done on that message, and there's nothing we can do about the DEBUG(1+2) case. I did a function that requires one to write mixin(myDebug("1+2")); but that's not as good, especially because of the quoting that makes most IDE's unaware of the syntax inside (maybe monod would work but still...). However there could be a clean D solution that alleviates need for macros: I'd like to add __ARGS__ to the list of __FILE__, __LINE__, __FUNC___: P1) 1st proposal: __ARGS__ is a string representing the comma separated list of arguments passed: void DEBUG(T,A)(T a, A args=__ARGS__){writeln(args,"=",a);} void DEBUG2(T1,T2,A)(T1 a1,T2 a2, A args=__ARGS__){writeln(args);} DEBUG(1+ 2); //will print "1+ 2=3", ie args="1+ 2" DEBUG(1+ 2, 3*3); //will print "1+ 2,3*3" (ie normalize the comma separation) P2) same but __ARGS__ is string[] with one string per argument; the compiler already did the job of parsing, might as well use it: void DEBUG(T)(T a1, T a2, string[] args=__ARGS__){ writeln(args[0],"=",a1); writeln(args[1],"=",a2); } A question: whether or not to include the first argument in a UFCS/member function call ("hello".fun(1+2) ). P3) additionally, create a __CONTEXT__ that is a struct consisting of __ARGS__,__FILE__, __LINE__, __FUNC___. This has been proposed before and makes even more sense now. Additionally, it could give info on whether the call was UFCS'd or not, etc, information which is lost otherwise (I don't think traits could help distinguish which version was called, a.fun(b) or fun(a,b)). |
February 01, 2013 Re: feature request: __ARGS__ for logging (cf __FILE__, __LINE__, __FUNC___) | ||||
---|---|---|---|---|
| ||||
Posted in reply to timotheecour | On 2013-02-01 11:34, timotheecour wrote: > One of the rare features I miss in C/C++ is stringification macro using > "#x": > > --- > #include ... > #define DEBUG(x) disp_val(#x,x) > template<typename T> > void disp_val(const char*name, const T& x) {std::cout << name << "=" << x;} > int main(){ > DEBUG(1+2); //will print 1+2=3 (and we can add line, file and func info) > ASSERT(1+2==4); //can also be defined such that it'll print 1+2==4 > failed... > } > --- > > In D, we have built-in assert message that'll print the failing > expression "1+2==4 failed" in case of failure but that's about it: no > further processing can be done on that message, and there's nothing we > can do about the DEBUG(1+2) case. I did a function that requires one to > write mixin(myDebug("1+2")); but that's not as good, especially because > of the quoting that makes most IDE's unaware of the syntax inside (maybe > monod would work but still...). > > However there could be a clean D solution that alleviates need for macros: > I'd like to add __ARGS__ to the list of __FILE__, __LINE__, __FUNC___: > > P1) 1st proposal: > __ARGS__ is a string representing the comma separated list of arguments > passed: > void DEBUG(T,A)(T a, A args=__ARGS__){writeln(args,"=",a);} > void DEBUG2(T1,T2,A)(T1 a1,T2 a2, A args=__ARGS__){writeln(args);} > DEBUG(1+ 2); //will print "1+ 2=3", ie args="1+ 2" > DEBUG(1+ 2, > 3*3); > //will print "1+ 2,3*3" (ie normalize the comma separation) > > P2) same but __ARGS__ is string[] with one string per argument; the > compiler already did the job of parsing, might as well use it: > > void DEBUG(T)(T a1, T a2, string[] args=__ARGS__){ > writeln(args[0],"=",a1); > writeln(args[1],"=",a2); > } > > A question: whether or not to include the first argument in a > UFCS/member function call ("hello".fun(1+2) ). > > P3) > additionally, create a __CONTEXT__ that is a struct consisting of > __ARGS__,__FILE__, __LINE__, __FUNC___. This has been proposed before > and makes even more sense now. Additionally, it could give info on > whether the call was UFCS'd or not, etc, information which is lost > otherwise (I don't think traits could help distinguish which version was > called, a.fun(b) or fun(a,b)). Sounds like an ugly hack for AST macros. This is a proposal for AST macros I've been working on. It's not finished but here it is: https://dl.dropbox.com/u/18386187/ast_macros.html -- /Jacob Carlborg |
February 01, 2013 Re: feature request: __ARGS__ for logging (cf __FILE__, __LINE__, __FUNC___) | ||||
---|---|---|---|---|
| ||||
Posted in reply to timotheecour | .stringof does pretty much the same, but, unfortunately, there is no way to pass an expression to template/function without evaluating it. |
February 01, 2013 Re: feature request: __ARGS__ for logging (cf __FILE__, __LINE__, __FUNC___) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 02/01/2013 11:54 AM, Jacob Carlborg wrote:
> ...
>
> Sounds like an ugly hack for AST macros. This is a proposal for AST
> macros I've been working on. It's not finished but here it is:
>
> https://dl.dropbox.com/u/18386187/ast_macros.html
>
Make sure to include some way to pattern match on the syntax trees. (Otherwise we are back to manual parsing of the ast.toString() output.)
|
February 01, 2013 Re: feature request: __ARGS__ for logging (cf __FILE__, __LINE__, __FUNC___) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 2013-02-01 12:24, Timon Gehr wrote: > Make sure to include some way to pattern match on the syntax trees. > (Otherwise we are back to manual parsing of the ast.toString() output.) Why would pattern matching be needed? -- /Jacob Carlborg |
February 01, 2013 Re: feature request: __ARGS__ for logging (cf __FILE__, __LINE__, __FUNC___) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | Jacob Carlborg: > This is a proposal for AST macros I've been working on. > It's not finished but here it is: > https://dl.dropbox.com/u/18386187/ast_macros.html Maybe it's the first serious proposal for D macros I see :-) Is it possible to re-use the <[ ]> syntax (and $...) for other purposes? Have you seen the macros of Scala language? http://scalamacros.org/ Regarding the attribute macros, my main use case for them is to extend the D type system in some ways. How well is such usage supported? Bye, bearophile |
February 01, 2013 Re: feature request: __ARGS__ for logging (cf __FILE__, __LINE__, __FUNC___) | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 2013-02-01 15:35, bearophile wrote: > Maybe it's the first serious proposal for D macros I see :-) > > Is it possible to re-use the <[ ]> syntax (and $...) for other purposes? That syntax is just an abstract syntax, it does not need to look like that. I'm thinking we could do something similar to Scala's reify macro. I call this the "ast" macro. Look at the header "The AST Macro". But to answer your question, no. It didn't cross my mind. > Have you seen the macros of Scala language? http://scalamacros.org/ Yes, this proposal is basically the same as macros in Scala, just adapted the syntax for D. > Regarding the attribute macros, my main use case for them is to extend > the D type system in some ways. How well is such usage supported? It might be possible, depending on what you want/need. I'm thinking you can do something like this: @foo int a; Which is replaced with: Foo!(int) a; It's a different type so depending on how you look at it you could say it affected the type system. -- /Jacob Carlborg |
February 01, 2013 Re: feature request: __ARGS__ for logging (cf __FILE__, __LINE__, __FUNC___) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 02/01/2013 02:03 PM, Jacob Carlborg wrote:
> On 2013-02-01 12:24, Timon Gehr wrote:
>
>> Make sure to include some way to pattern match on the syntax trees.
>> (Otherwise we are back to manual parsing of the ast.toString() output.)
>
> Why would pattern matching be needed?
>
Analysis and rewriting.
|
February 01, 2013 Re: feature request: __ARGS__ for logging (cf __FILE__, __LINE__, __FUNC___) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 2013-02-01 16:36, Timon Gehr wrote: > Analysis and rewriting. I'm just thinking an API similar to a reflection API. Something like: Ast!(Class) c; foreach (Ast!(Member) m ; c.members) { // do something with each member } Sure it would be easier and better looking with pattern matching. -- /Jacob Carlborg |
February 01, 2013 Re: feature request: __ARGS__ for logging (cf __FILE__, __LINE__, __FUNC___) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | Jacob Carlborg: > But to answer your question, no. It didn't cross my mind. OK. (I have asked because syntax costs, so it's good to use it as much as possible, if it doesn't lead to ambiguities). > Yes, this proposal is basically the same as macros in Scala, just adapted the syntax for D. I think Scala macros are simple to implement :-) > It might be possible, depending on what you want/need. I'm thinking you can do something like this: > > @foo int a; > > Which is replaced with: > > Foo!(int) a; > > It's a different type so depending on how you look at it you could say it affected the type system. I meant something more like (the now closed) Treehydra: https://developer.mozilla.org/en-US/docs/Treehydra_Manual Bye, bearophile |
Copyright © 1999-2021 by the D Language Foundation