> Macro expansion can place a literal or generated lambda expression there instead of using FUNCALL at all.
Not quite. This, for example, does not work:
(defmacro foo () '(lambda (x) x))
((foo) 1)
A macro can expand into a form whose CAR is a literal lambda expression, but because there is always an equivalent LET form I can't think of a circumstance where this can do anything but obfuscate the code.
Personally, I think this is a flaw in the design of CL. Long ago I proposed an extension that would allow the CAR of a form to be a macro:
I think it's cool for pedagogy because it lets you do things like directly define the Y combinator in CL without a ton of FUNCALLs. But it never caught on.
A “rap sheet” is a criminal record, and a “bum rap” meant a false accusation (or even a false conviction). Even when the charge was valid, it should come as no surprise, a guilty party might claim it was a “bum rap” just to save face.
Man, that digression into unexec reminds me of how ugly Emacs is under the covers. I do really appreciate having elisp available to creatively enhance my editor but... ugh.
So then comes the perennial reminder of Guile/Emacs. There'd be no unexec (in theory) and while this appears to be design-intent from a Common Lisp, maybe it could be cleaned up in bytecode. The last Guile/Emacs push was, I think, a Google SoC project with some community followup from someone who knows far more about Emacs and Lisp than I. Guile 2.2 is out and is really sweet (fast, feels modern, kind of exciting). I wonder if it's time for another push to completion? Has anyone gave the experimental branch a spin lately?
The useful thing about unexec is that it is general. I ported it from Emacs to GNU Make about ten years ago. I was then able to instantly run incremental make jobs (where the rule tree of included Makefiles was so large that it otherwise took 30 seconds between typing make and the command to rebuild your file being dispatched!) GNU Make doesn't use any special data structures; just malloced structs with arbitrary pointers that no garbage collector is informed about.
But is it? I don't actually think it's bad design. Having system images of a pre-loaded heap is pretty common in many systems and languages. How such systems are generated and loaded vary, but they always come with some tricky issues. This is especially common in lisp-like systems.
The whole lisp implementation is emacs is a bit crummy, but I don't get the excessive criticism against unexec. I consider lexical binding a much a much bigger oversight.
Few things are pretty "under the covers." In large, that is why we have cover panels, period. Have you looked under the panel of your computer lately? :)
What an interesting question! Many computers are an impenetrable "unibody" or otherwise glued-together cryptex these days :).
Guile/Emacs offers a way to clear a staggering amount of baggage, offering some great features, while mostly keeping add-on packages compatible. You'd think it would get more love. I use Emacs (having switch from Vim because of elisp) but I'm definitely not well positioned to do anything here :/. As it is, I'm a very strange Emacs user: no emacs-server and always '-nw' inside tmux.
a list (lambda () (print :foo)) is not code:
But the unquoted lambda form is code, since Common Lisp has a LAMBDA macro The LAMBDA macro transforms it into a FUNCTION special form with an embedded lambda expression: Thus in Common Lisp we can evaluate:a) the special form FUNCTION:
b) the same, but using #' as a short version: c) or the macro LAMBDA, which expands into a)