digitalmars.D - Template-based Preprocessing
- Garett Bass (28/28) Sep 03 2006 D's template mechanism is very promising, but I'm frequently frustrated ...
- Garett Bass (2/5) Sep 03 2006 Can someone explain to me how lazy is equivalent to defmac? After readi...
- Don Clugston (9/62) Sep 03 2006 I've previously suggested the 'identifier' keyword for string pasting.
- Walter Bright (3/12) Sep 04 2006 Not a bad idea, but it would require a lot of internal rewriting of the
- Garett Bass (19/21) Sep 04 2006 Rewriting the front-end only or the back-end too? I'm disappointed to h...
- Walter Bright (2/7) Sep 04 2006 The front end only.
- Reiner Pope (15/28) Sep 20 2006 Why is implementing 'identifier' different from/harder than supporting
- Georg Wrede (5/37) Sep 23 2006 Because in the above code the identifiers a,b,c do exist right from the
- Garett Bass (22/26) Sep 04 2006 Thanks, Don! I now recall your suggestion from a thread I prompted abou...
- Don Clugston (7/41) Sep 04 2006 I don't know. It's clearly easy to get through the syntactic pass. But
- Kirk McDonald (27/74) Sep 04 2006 I have a use-case. In the Python/C API, a module must have an init
- Bruno Medeiros (11/54) Sep 05 2006 Indeed I was about to ask that too, what would be the use of such a
D's template mechanism is very promising, but I'm frequently frustrated by the lack of C-preprocessor-equivalent power. D templates currently provide no means for insertion of arbitrarily parameterized blocks of code, but I think they potentially could. One feature I'm sorely missing that the C preprocessor happily provides is the ability to insert blocks of code parameterized by an arbitrary identifier, e.g.: // C/C++ #define SERIALIZABLE(type, identifier) \ type identifier; \ \ return toString(identifier); \ } class Foo { SERIALIZABLE(int, i); }; Though this can't be reproduced by D templates, I'd like to suggest the following: // D (suggestion) template Serializable(T, token I) { T I; string serialize_`I`() { return toString(I); } } class Foo { mixin Serializable!(int, i); } Here I've used backticks to expand the identifier into code akin to the C to mean something different from "alias", since it need not specify an existing global identifier or alias. I'm not really satisfied with this suggestion, maybe C-preprocessor-style appropriate, and perhaps a different keyword than "token". I'm open to other ideas. I've not looked into the D front-end codebase yet, but I'm taking a compilers class this semester, so I was hoping I might be able implement this eventually. Any ideas whether this is doable? Any objections? Regards, Garett
Sep 03 2006
Walter Bright wrote:defmac is often trotted out as a big productivity gainer in Lisp, because with it one can define one's own syntax. D's lazy evaluation does the equivalent.Can someone explain to me how lazy is equivalent to defmac? After reading Paul Graham's "Hackers & Painters", I thought defmac was more like #define macros.
Sep 03 2006
Garett Bass wrote:D's template mechanism is very promising, but I'm frequently frustrated by the lack of C-preprocessor-equivalent power. D templates currently provide no means for insertion of arbitrarily parameterized blocks of code, but I think they potentially could. One feature I'm sorely missing that the C preprocessor happily provides is the ability to insert blocks of code parameterized by an arbitrary identifier, e.g.: // C/C++ #define SERIALIZABLE(type, identifier) \ type identifier; \ \ return toString(identifier); \ } class Foo { SERIALIZABLE(int, i); }; Though this can't be reproduced by D templates, I'd like to suggest the following: // D (suggestion) template Serializable(T, token I) { T I; string serialize_`I`() { return toString(I); } } class Foo { mixin Serializable!(int, i); } Here I've used backticks to expand the identifier into code akin to the "token" to mean something different from "alias", since it need not specify an existing global identifier or alias. I'm not really satisfied with this suggestion, maybe (string-pasting) would be more appropriate, and perhaps a different keyword than "token". I'm open to other ideas.I've previously suggested the 'identifier' keyword for string pasting. Stringizing is already possible, you can find the code for symbolnameof!() in dsource/ddl/meta, together with qualifiednameof!() which is significantly more powerful than anything in C++. With identifier, you'd write: string identifier("serialize_" ~ symbolnameof!(I))() { return toString(I); }I've not looked into the D front-end codebase yet, but I'm taking a compilers class this semester, so I was hoping I might be able implement this eventually. Any ideas whether this is doable? Any objections? Regards, Garett
Sep 03 2006
Don Clugston wrote:I've previously suggested the 'identifier' keyword for string pasting. Stringizing is already possible, you can find the code for symbolnameof!() in dsource/ddl/meta, together with qualifiednameof!() which is significantly more powerful than anything in C++. With identifier, you'd write: string identifier("serialize_" ~ symbolnameof!(I))() { return toString(I); }Not a bad idea, but it would require a lot of internal rewriting of the compiler to implement.
Sep 04 2006
Walter Bright wrote:Not a bad idea, but it would require a lot of internal rewriting of the compiler to implement.Rewriting the front-end only or the back-end too? I'm disappointed to hear that it is so much work; this would really wrap up the boilerplate for my serialization library: template Serializable(T, char[] I) { T identifier(I); string identifier("serialize_" ~ I)() { return toString(identifier(I)); } } class Foo { mixin Serializable!(int, "i"); } Foo should expand to the equivalent of: class Foo { int i; string serialize_i() { return toString(i); } } Of course there would also be a static registrar that would register the dynamically generated serialization and deserialization delegates at the class level at static initialization time, and associate them by string. With a couple other components, this allows serializable classes enough reflection to serialize and deserialize their members and properties.
Sep 04 2006
Garett Bass wrote:Walter Bright wrote:The front end only.Not a bad idea, but it would require a lot of internal rewriting of the compiler to implement.Rewriting the front-end only or the back-end too?
Sep 04 2006
Walter Bright wrote:Don Clugston wrote:Why is implementing 'identifier' different from/harder than supporting the following: template foo(char[] name) { bool bar; static if (name == "a") alias bar a; static if (name == "b") alias bar b; static if (name == "c") alias bar c; ... } Since we can already emulate the 'identifier' keyword by doing this, what's the difficulty in making this supported in the compiler? Cheers, ReinerI've previously suggested the 'identifier' keyword for string pasting. Stringizing is already possible, you can find the code for symbolnameof!() in dsource/ddl/meta, together with qualifiednameof!() which is significantly more powerful than anything in C++. With identifier, you'd write: string identifier("serialize_" ~ symbolnameof!(I))() { return toString(I); }Not a bad idea, but it would require a lot of internal rewriting of the compiler to implement.
Sep 20 2006
Reiner Pope wrote:Walter Bright wrote:Because in the above code the identifiers a,b,c do exist right from the start, whereas with the identifier suggestion they'd be "born" at a later stage of processing, and this means grafting them late into the compiler data structures.Don Clugston wrote:Why is implementing 'identifier' different from/harder than supporting the following: template foo(char[] name) { bool bar; static if (name == "a") alias bar a; static if (name == "b") alias bar b; static if (name == "c") alias bar c; ... } Since we can already emulate the 'identifier' keyword by doing this, what's the difficulty in making this supported in the compiler?I've previously suggested the 'identifier' keyword for string pasting. Stringizing is already possible, you can find the code for symbolnameof!() in dsource/ddl/meta, together with qualifiednameof!() which is significantly more powerful than anything in C++. With identifier, you'd write: string identifier("serialize_" ~ symbolnameof!(I))() { return toString(I); }Not a bad idea, but it would require a lot of internal rewriting of the compiler to implement.
Sep 23 2006
Don Clugston wrote:I've previously suggested the 'identifier' keyword for string pasting. Stringizing is already possible, you can find the code for symbolnameof!() in dsource/ddl/meta, together with qualifiednameof!() which is significantly more powerful than anything in C++.Thanks, Don! I now recall your suggestion from a thread I prompted about a year ago. I've updated my example to use your suggested 'identifier' keyword, as this obviates the need for my suggested 'token' keyword: template Serializable(T, char[] I) { T identifier(I); string identifier("serialize_" ~ I)() { return toString(identifier(I)); } } class Foo { mixin Serializable!(int, "i"); } Foo should expand to the equivalent of: class Foo { int i; string serialize_i() { return toString(i); } } Do you have any idea what's involved in implementing the 'identifier' keyword as described here? Regards, Garett
Sep 04 2006
Garett Bass wrote:Don Clugston wrote:I don't know. It's clearly easy to get through the syntactic pass. But does it cause problems during name lookup? More importantly, would it encourage bad coding styles? IMHO, it needs some convincing use cases -- or, if Walter gets more experimental post-1.0, this would be an extremely cool thing to try out. (It would kill one of the last metaprogramming things C++ still has compared to D).I've previously suggested the 'identifier' keyword for string pasting. Stringizing is already possible, you can find the code for symbolnameof!() in dsource/ddl/meta, together with qualifiednameof!() which is significantly more powerful than anything in C++.Thanks, Don! I now recall your suggestion from a thread I prompted about a year ago. I've updated my example to use your suggested 'identifier' keyword, as this obviates the need for my suggested 'token' keyword: template Serializable(T, char[] I) { T identifier(I); string identifier("serialize_" ~ I)() { return toString(identifier(I)); } } class Foo { mixin Serializable!(int, "i"); } Foo should expand to the equivalent of: class Foo { int i; string serialize_i() { return toString(i); } } Do you have any idea what's involved in implementing the 'identifier' keyword as described here?
Sep 04 2006
Don Clugston wrote:Garett Bass wrote:I have a use-case. In the Python/C API, a module must have an init function named "init" ~ module_name. This function is called by Python when the module is imported. The init function must furthermore contain a call to the Py_InitModule function (or one of its variants), which takes the name of the module as a string argument. If we have a module named "foo", we might say: extern(C) export void initfoo() { Py_InitModule("foo", null); } Boost.Python wraps this business with some preprocessor tricks. The following is more or less equivalent to the above code: BOOST_PYTHON_MODULE(foo) { } I cannot do this in Pyd. The only difference between Pyd code and the first example above is that the user must call Pyd's module_init function rather than Python's Py_InitModule. With the proposed "identifier" keyword, I could get rid of the burdensome "init" function definition, and the redundancy of specifying "foo" twice (both in the function name and in the call to the init function). More generally, this syntax would help D interface with other C libraries that expect special function names like this. -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.orgDon Clugston wrote:I don't know. It's clearly easy to get through the syntactic pass. But does it cause problems during name lookup? More importantly, would it encourage bad coding styles? IMHO, it needs some convincing use cases -- or, if Walter gets more experimental post-1.0, this would be an extremely cool thing to try out. (It would kill one of the last metaprogramming things C++ still has compared to D).I've previously suggested the 'identifier' keyword for string pasting. Stringizing is already possible, you can find the code for symbolnameof!() in dsource/ddl/meta, together with qualifiednameof!() which is significantly more powerful than anything in C++.Thanks, Don! I now recall your suggestion from a thread I prompted about a year ago. I've updated my example to use your suggested 'identifier' keyword, as this obviates the need for my suggested 'token' keyword: template Serializable(T, char[] I) { T identifier(I); string identifier("serialize_" ~ I)() { return toString(identifier(I)); } } class Foo { mixin Serializable!(int, "i"); } Foo should expand to the equivalent of: class Foo { int i; string serialize_i() { return toString(i); } } Do you have any idea what's involved in implementing the 'identifier' keyword as described here?
Sep 04 2006
Don Clugston wrote:Garett Bass wrote:Indeed I was about to ask that too, what would be the use of such a feature? I have to say I'm a bit skeptical, it feels way hackish. I've read Kirk's reply about Python/C API, but it is only required there because Python interfacing requires manipulation of object code implementation-level semantics (the function names), as could require any other interfacing with a C library . But what about any actual "conceptual"/"design" use? -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DDon Clugston wrote:I don't know. It's clearly easy to get through the syntactic pass. But does it cause problems during name lookup? More importantly, would it encourage bad coding styles? IMHO, it needs some convincing use cases -- or, if Walter gets more experimental post-1.0, this would be an extremely cool thing to try out. (It would kill one of the last metaprogramming things C++ still has compared to D).I've previously suggested the 'identifier' keyword for string pasting. Stringizing is already possible, you can find the code for symbolnameof!() in dsource/ddl/meta, together with qualifiednameof!() which is significantly more powerful than anything in C++.Thanks, Don! I now recall your suggestion from a thread I prompted about a year ago. I've updated my example to use your suggested 'identifier' keyword, as this obviates the need for my suggested 'token' keyword: template Serializable(T, char[] I) { T identifier(I); string identifier("serialize_" ~ I)() { return toString(identifier(I)); } } class Foo { mixin Serializable!(int, "i"); } Foo should expand to the equivalent of: class Foo { int i; string serialize_i() { return toString(i); } } Do you have any idea what's involved in implementing the 'identifier' keyword as described here?
Sep 05 2006