digitalmars.D - Ubermacros a la Nemerle
- Andy Friesen (45/45) Jun 08 2004 Nemerle (http://nemerle.org) is a hybrid functional/imperative language
- Ivan Senji (7/52) Jun 08 2004 Lately i have been trying to put my finger on a feature that would give
- Brad Anderson (8/69) Jun 08 2004 If it truly is like Lisp's macros, it would be a feature of D that not
Nemerle (http://nemerle.org) is a hybrid functional/imperative language What makes it stand out is its macro facilities, which more or less cover any sort of language extension that I can even imagine. Nemerle macros effectively boil down to functions that are run by the compiler. They accept parse trees as arguments, and return a parse tree element which is injected into the code. It is my understanding that Lisp macros work on the same principle, but this is the first time I've seen it in a form that doesn't seem magical. (maybe I just haven't read enough Lisp yet) Currently, Nemerle macros are compiled into separate DLLs, which, while somewhat klunky, allows closed-source people to use them for libraries and such. It also makes it abundantly clear when things are happening and what dependancies exist. (macros are needed by the compiler, not the resulting binary) Hypothetical example: import std.compiler; Expression print(Expression args) { // would presumably raise a SyntaxError if 'args' is not an // argument list auto Expression[] argList = decomposeArgumentList(args); Expression[] result foreach (Expression arg; args) { // <[ stuff ]> is an Expression object representing the // enclosed hunk of code. // $arg is used to denote that the argument is inserted into // the block, as opposed to literally inserting the symbol // 'arg'. Maybe there's a nicer looking alternative. result ~= <[ stdio.write($arg) ]>; } result ~= <[ stdio.write('\n') ]>; // Convert the Expression[] into a single { ... } block and return it. return composeBlock(result); } This would expand the expression 'print(x,y,z,blah,"thing", 3.141596, 2+4i)' to a {} block containing a bunch of of stdio.write() calls, ending with a newline. Something tells me this is just a hair too ambitious for D 1.0, but it does look to be implementable enough, and has a pretty big impact on what can be conveniently expressed within the language. (if I'm reading the source correctly, almost all of Nemerle's syntax is implemented via its own macros) Thoughts? -- andy
Jun 08 2004
Lately i have been trying to put my finger on a feature that would give ability to generate code at compile time (inspired by VHDL's generate) but i had no idea how this would work.But it could be a Very powerful feature. D 2.0? "Andy Friesen" <andy ikagames.com> wrote in message news:ca56h1$2k4h$1 digitaldaemon.com...Nemerle (http://nemerle.org) is a hybrid functional/imperative language What makes it stand out is its macro facilities, which more or less cover any sort of language extension that I can even imagine. Nemerle macros effectively boil down to functions that are run by the compiler. They accept parse trees as arguments, and return a parse tree element which is injected into the code. It is my understanding that Lisp macros work on the same principle, but this is the first time I've seen it in a form that doesn't seem magical. (maybe I just haven't read enough Lisp yet) Currently, Nemerle macros are compiled into separate DLLs, which, while somewhat klunky, allows closed-source people to use them for libraries and such. It also makes it abundantly clear when things are happening and what dependancies exist. (macros are needed by the compiler, not the resulting binary) Hypothetical example: import std.compiler; Expression print(Expression args) { // would presumably raise a SyntaxError if 'args' is not an // argument list auto Expression[] argList = decomposeArgumentList(args); Expression[] result foreach (Expression arg; args) { // <[ stuff ]> is an Expression object representing the // enclosed hunk of code. // $arg is used to denote that the argument is inserted into // the block, as opposed to literally inserting the symbol // 'arg'. Maybe there's a nicer looking alternative. result ~= <[ stdio.write($arg) ]>; } result ~= <[ stdio.write('\n') ]>; // Convert the Expression[] into a single { ... } block and return it. return composeBlock(result); } This would expand the expression 'print(x,y,z,blah,"thing", 3.141596, 2+4i)' to a {} block containing a bunch of of stdio.write() calls, ending with a newline. Something tells me this is just a hair too ambitious for D 1.0, but it does look to be implementable enough, and has a pretty big impact on what can be conveniently expressed within the language. (if I'm reading the source correctly, almost all of Nemerle's syntax is implemented via its own macros) Thoughts? -- andy
Jun 08 2004
If it truly is like Lisp's macros, it would be a feature of D that not many languages have, and would truly be for power programmers. (According to Paul Graham). If Walter implemented this, he would be able to point people to this capability and tell them to try it themselves instead of having them/us wait for a new release. BA Andy Friesen wrote:Nemerle (http://nemerle.org) is a hybrid functional/imperative language What makes it stand out is its macro facilities, which more or less cover any sort of language extension that I can even imagine. Nemerle macros effectively boil down to functions that are run by the compiler. They accept parse trees as arguments, and return a parse tree element which is injected into the code. It is my understanding that Lisp macros work on the same principle, but this is the first time I've seen it in a form that doesn't seem magical. (maybe I just haven't read enough Lisp yet) Currently, Nemerle macros are compiled into separate DLLs, which, while somewhat klunky, allows closed-source people to use them for libraries and such. It also makes it abundantly clear when things are happening and what dependancies exist. (macros are needed by the compiler, not the resulting binary) Hypothetical example: import std.compiler; Expression print(Expression args) { // would presumably raise a SyntaxError if 'args' is not an // argument list auto Expression[] argList = decomposeArgumentList(args); Expression[] result foreach (Expression arg; args) { // <[ stuff ]> is an Expression object representing the // enclosed hunk of code. // $arg is used to denote that the argument is inserted into // the block, as opposed to literally inserting the symbol // 'arg'. Maybe there's a nicer looking alternative. result ~= <[ stdio.write($arg) ]>; } result ~= <[ stdio.write('\n') ]>; // Convert the Expression[] into a single { ... } block and return it. return composeBlock(result); } This would expand the expression 'print(x,y,z,blah,"thing", 3.141596, 2+4i)' to a {} block containing a bunch of of stdio.write() calls, ending with a newline. Something tells me this is just a hair too ambitious for D 1.0, but it does look to be implementable enough, and has a pretty big impact on what can be conveniently expressed within the language. (if I'm reading the source correctly, almost all of Nemerle's syntax is implemented via its own macros) Thoughts? -- andy
Jun 08 2004