Hacker News new | ask | show | jobs
by kazinator 3521 days ago
In Lisp-1 dialects such as Scheme, macros are not in the "matrix containing normal variables".

You cannot say with a straight face that "all elements of a form are evaluated equally and then the rest values are applied as args to the first value" because the counterexample (let ((a 42) a) doesn't work that way.

The Lisp-1 has to treat the leftmost position specially to determine whether let is a macro to be expanded or a special operator. That will not happen in a form like this (list 3 let 4).

In the TXR Lisp dialect (which provides Lisp-1 and Lisp-2 style evaluation), I fix this. In the Lisp-1 style forms, macros are not allowed. So [let ((a 3)) a] is a priori nonsense. The let symbol's position is evaluated exactly like the other positions, without being considered a macro (other than a symbol macro, which all the other positions may be).

The combination of Lisp-2 and Lisp-1 in one dialect let me have a cleaner, purer Lisp-1 in which that half-truth about all positions of a Lisp-1 form being equally evaluated is literally true, always.

Lisp-2 for macros and special ops, Lisp-1 for HOF pushing: beautiful. (list list) works, no funcall anywhere, and even if let is a variable that holds a function [let 42] call the damn thing:

  1> (let ((let (lambda (n) n))) [let 3])
  1
The let operator is not shadowed:

  2> (let ((let (lambda (n) n)))
       (let ((a 'b))
         [let a])) ;; let var visible across inner let
  b
Basically, as far as I'm concerned, this whole Lisp-1 versus Lisp-2 squabbling is an obsolete debate and solved problem (by me).