Consider merging eval, eval-ast and macroexpand
Hello.
A suggestion may simplify the process, or at least most existing implementations as far as I have experimented.
Please be indulgent for the argumentation, english is not my native language.
-
EVALshould switch on the type ofast. The fact that list evaluation is normally a function call would be easyer to understand. In the current process,eval-astis confusing because it has two distinct purposes:-
evaluate all elements of a sequence. This deserves a subprogram (with a better name) in some languages, but for most existing languages with native
map, following the process and callingeval-astleads to unneeded boxing and unboxing. -
the part of
EVALoutside the apply phase. In languages with a case/switch statement or pattern matching, this leads to unneeded complexity because the call toeval-astbreaks the natural destructuring ofast.
-
-
the right place for macro expansion should be the apply phase. The only differences between a function call and a macro call are that the arguments are not evaluated and that
EVAL(or better, a TCO continuation) is called on the result. A strong argument for this suggestion is that, while debugging,macroexpandbecomes redundant with a display of theEVALarguments at the start of the TCO loop, which is quite useful and well understood far sooner. Moreover, the display would print two lines for each macro evaluation, while the currentmacroexpanddoes a loop before printing anything.
Mixing the suggestions, the EVAL structure becomes:
- switch on the type of
ast. All cases are already described in the process for non-list types and empty lists. - if
astis a non-empty list, evaluate its first argument (by the way, the result may be a macro even if the first argument is not a symbol). - switch on the type of the evaluated first argument. If it is a macro, apply it on the unevaluated arguments and continue the TCO loop. If it is a function, apply it on the evaluated arguments and return the result (on some implementations, there are different kinds of functions, but this only extends the switch cases and does not add complexity in the
EVALstructure).