Hacker News new | ask | show | jobs
by fiddlerwoaroof 2892 days ago
A lot of the comments mention reasons. In my experience, once you get used to a lisp-2 programming in a lisp-1 feels limiting: you can’t just write

    (def str “foo”)
In Clojure, because you’ll shadow the builtin definition of str (which leads to really weird bugs). But, this means that there’s one more thing to think about when naming your variables.

Additionally, I think we’re pretty used to “separate namespaces” for nouns and verbs in normal languages: it’s fairly rare, for example, for the word “run” to be ambiguous between its noun use and it’s verb use, in the context of a sentence.

1 comments

Lisp-1 fails to prevent the situation that the left position of a form is treated specially, both syntactically and semantically. Yet, the evaluation-strategy is sold that way to programmers: "look, symbols all positions of a compound form are treated uniformly".

It is not true syntactically, because special operators are recognized only in the leftmost position, as are function-style macros.

But it is not even true when all symbols in the form are variable bindings. Because at some point, the function is called, and that is not uniform. The leftmost thing is treated as a function being invoked, and the others as arguments being passed. These are different categories. We take the leftmost object and activate its ability to behave as a process; and we don't do that for the other objects. That's effectively a different semantic space.

Objects potentially have two "semantic bindings": a binding to the ability to behave as a function (denoting a process which takes arguments and produces values, and possibly side effects) and the trivial binding to the value that they denote; e.g. the integer object 3 to the abstract integer three. These bindings are two spaces, effectively. Therefore, Lisp-1 doesn't get away from two spaces. It resolves the leftmost object of a call form in the "function behavior space" and the remaining objects in the "value denotational space", in order to bring about a function call.

Lisp-2 has a cleaner story/explanation of operators. It simply embraces the idea that the left position and argument positions are different, through the entire evaluation stack, rather than trying to pretend they are the same.

In a Lisp-2, you cannot write an expression which refers to an operator as if it were a variable. Whereas in Lisp-1, meaningless nonsense like (progn progn) is possible, in a Lisp-2 this can exist with a meaning. The potential that we can give any form meaning is a core theme in Lisp. The fact that we can bind a progn variable so that (progn progn) works is more "Lispy" than having to give up and conclude that it's an absurdity.