mal icon indicating copy to clipboard operation
mal copied to clipboard

Consider merging eval, eval-ast and macroexpand

Open asarhaddon opened this issue 4 years ago • 0 comments

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.

  • EVAL should switch on the type of ast. The fact that list evaluation is normally a function call would be easyer to understand. In the current process, eval-ast is 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 calling eval-ast leads to unneeded boxing and unboxing.

    • the part of EVAL outside the apply phase. In languages with a case/switch statement or pattern matching, this leads to unneeded complexity because the call to eval-ast breaks the natural destructuring of ast.

  • 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, macroexpand becomes redundant with a display of the EVAL arguments 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 current macroexpand does 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 ast is 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 EVAL structure).

asarhaddon avatar Aug 21 '21 18:08 asarhaddon