Post a Comment
I'm impressed. I expected YA (worthless) exposition of C++ template metaprogramming, but I got an overview of several different techniques, even including Scheme/Lisp, which is pretty much the only language with builtin metaprogramming worthy of the name.
Nothing here new or revolutionary here, but interesting reading and there's likely something useful to be found.
is going to be a fantastic addition to .Net 2.0...I know there's nothing new or revolutionary about it, but we .Net folks have long been looking forward to something like this.
http://msdn2.microsoft.com/en-us/library/80h6baz2(en-US,VS.80).aspx
The ability to define out own DSL will lend itself pretty well to this paradigm also.
The Scheme example doesn't tickle my asthetic fancy like the Common Lisp version does (sorry that OSNews borks the formatting completely):
; define vector containing square roots
(defmacro define-roots (name (start end))
`(setf ,name
(vector ,@(loop for in from start to end
collect (sqrt i)))))
; example usage
(define-roots root-table (5 20))
The idea of language sensitivity as implemented in Scheme is IMO the best kind of metaprogramming, but it could still be improved: Instead of using some obscure define-syntax or similar special form, they could just as well let a regular program transform the syntax, which in the end is just another data structure (and possibly transform the pattern matching of define-syntax into a general language feature). defmacro would still be the same, since it does not define a code transformer but a modified evaluator.
To explain, I'll show how one would implement "let" this way. my-defsyntax is the special form to define code transformers, which works like defining a function but is applied automatically to code when the defined symbol is seen (this is a bit vague, I can define this more strictly if you want):
(my-defsyntax (let defs body)
(list
(list lambda (map car defs) body)
(map cdr defs)
)
)
- Morin
I'm a little confused on how this is different from defmacro. you're example above looks like this in Common Lisp:
(defmacro mylet (defs body)
`(funcall #'(lambda ,(mapcar #'car defs) ,body)
,@(mapcar #'cadr defs)))
It can be used like:
(mylet ((a 1)(b 2)(q 3))
(format t "~A ~A ~A~%" a b q))
Semantically, it does precisely what you say. "defmacro is a special form to define code transformers, which works like defining a function but is applied automatically to code when the defined symbol is seen."
Actually, "defmacro" is itself a macro, but the result is the same. Under the hood, "defmacro" creates a function tied to the symbol "mylet". When the parser encounters a form like "(mylet ...)", it hands the code to that function, and subtitutes the original form with the resulting code.
In case anyone still reads this... I was referring to Scheme, where defmacro (AFAIK) defines a custom evaluator, not a code transformer. I.e. it is not a function (old code)->(new code) but a function (old environment,code)->(new environment,value)
But looks like CLISP already does what I had in mind.
- Morin



