3 ms·
I believe it has to do with namespaces for naming functions vs variables. A lisp-1 has one namespace that encompasses variables and functions. In a lisp-2 the
by FPGAhacker 7y ago
I believe it has to do with namespaces for naming functions vs variables. A lisp-1 has one namespace that encompasses variables and functions. In a lisp-2 they are separate and so it is possible to have a variable with the same name as a function.
- sdegutis 7y agoLisp-1 is pretty much the model JavaScript uses. Lisp-2 is what Emacs uses and it requires some extra features/functions to do functional programming.
- kazinator 7y agoThe nice thing in Lisp-2 is that Lisp code is not only made out of function calls, but also special operators. In a Lisp-1, simple variable bindings can shadow special operators. If you name a variable let, you're locked out of further let binding in that scope. That is ugly. Yet, you can hardly prevent let being used as a variable name. In a Lisp-2, we don't have this problem. We have a more benign version of it, rather: what happens if someone names a function let. That can be dealt with by a compiler warning or error. E.g. our implementation can warn that a special operator is redefined. And then it can cheerfully ignore the redefinition, so that let continues to work. Then there is the question, in a Lisp-1, given that we have a let operator, and operators and variables are in the same space, what the heck is the value of let as a variable? What should (let ((let let)) let) return? This is hand-waved away with something lame like let having an undefined value or whatever. This is ugly and points at Lisp-1 not being as clean and consistent as it is cracked up to be. With macros, it's possible for the same symbol to have both a function and macro binding! In a Lisp-2, that's like 2.5 namespaces. This is the TXR Lisp interactive listener of TXR 219. Quit with :quit or Ctrl-D on empty line. Ctrl-X ? for cheatsheet. 1> (defun foo (arg) (* 10 arg)) foo 2> (defmacro foo (arg) ^'(multiply ,arg by 10)) foo 3> (foo 15) (multiply 15 by 10) 4> (mapcar 'foo '(1 2 3)) (10 20 30) 5> (fboundp 'foo) t 6> (mboundp 'foo) t 7> (mmakunbound 'foo) foo 8> (mboundp 'foo) nil 9> (foo 10) 100 It is said glibly that Lisp-1 dialects uniformly evaluate all positions of a form, rather than treating the leftmost one specially. But that is actually not true. A Lisp-1 dialect, just like Lisp-2, looks at the first position and treats the expression specially if there is a special operator or macro there! (But: not if it's a symbol macro; yet, symbol macros and macros end up in the same namespace.) Moreover, after a function call form like (f x y) is evaluated (uniformly, to be sure), the semantics isn't uniform: the first value denotes a function (or other callable object), and the remaining values denote arguments to be applied to it. That's a fundamental asymmetry, shared with Lisp-2. Why fret about symmetry in the evaluation, when the semantics of the application itself is ultimately asymmetric. In the end it just boils down to the pragmatics: hygiene considerations versus not having to use funcall for working with higher order functions.