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.
Is your vau work available publicly? I find this stuff very interesting.
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 ; 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.
Yeah, compiling first-class macros can be very tricky. I cut them from the compiler for my own Lisp because I didn't see the benefit of having them (beyond them being neat). 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.
The thing about first-class macros, though, is that the macro expansion phase is still separate from the execution phase. It's just that both phases now happen at run time rather than having expansion at compile time.
> I.e., as I understand it, it's way easier to build a highly informative debugger into an interpreter than it is to attach a debugger to compiled code.
That makes sense. I couldn't have derived that from the original statement. Thanks.