4 ms·
If you know of some use-cases where first-class macros are useful, I'd love to hear about them. I might change my mind about cutting them. I got nothin' in
by gliese1337 14y ago
If you know of some use-cases where first-class macros are useful,
I'd love to hear about them. I might change my mind about cutting them.
I got nothin' in terms of practical use cases. It's mainly a research thing. It annoys me that Lisp function calls look exactly the same as macro calls, but in fact behave differently, and making macros first-class fixes things up so that same look == same behavior. That way you can do crazy stuff like
(map (fn (a) (apply or a)) '((#t #t)(#t #f)(#f #t)(#f #f)))
Where normally this would produce an error "or is not a procedure".
My interpreter implements both lambdas and macros as syntactic sugar on top of vau expressions, so if I had a good way of compiling vau expressions, then the first-class runtime macros would be automatic. In the interests of efficiency, I'd like some way of doing static analysis to do as much macro expansion as possible at initialization / compile time, but that's dang tricky figuring out which macros will end up bound to which names before runtime.
- groovy2shoes 14y agoYeah, Guile has first-class macros, but I've never been able to come up with a practical use for them, either. I still find them neat. Is your vau work available publicly? I find this stuff very interesting.
- gliese1337 14y agoYup. I've got it up on github at https://github.com/gliese1337/schrodinger-lisp https://github.com/gliese1337/schrodinger-lisp, with explanations blogged at http://gliese1337.blogspot.com/2012/04/schrodingers-equation-of-software.html http://gliese1337.blogspot.com/2012/04/schrodingers-equation... (first installment; there are later posts with the same tags describing incrementally added features). The syntactic sugar for macros isn't pushed to the public repository yet; not till I get a good blog post written up about it. But it's basically parallel to the operation of "wrap" in Kernel- where "wrap" creates a lambda by evaluating the arguments to a vau expression, "macro" evaluates the return value of a vau expression. I'm doing most the research stuff on the Schrodinger repository, and things that I like will end up eventually on https://github.com/gliese1337/vernal-lang https://github.com/gliese1337/vernal-lang ; I've stopped actively updating that repository for now because I'm contemplating re-implementing the "real" Vernal interpreter (as opposed to the "research-only" Schrodinger interpreter) in Go, so that there's only 1 level of interpretation going on instead of 2.