logoalt Hacker News

iFiretoday at 4:48 PM6 repliesview on HN

Since this is the largest gathering of LISP users I have seen, I have a question.

Why prefer lisp-1 over lisp-2 or vice-versa?


Replies

sphtoday at 8:32 PM

Having a separate namespace for functions is silly in that it only saves you from a small set of variable shadowing problems. It’s a hack, not a serious solution.

Jtsummerstoday at 5:11 PM

Ignoring all the other distinctions between lisps, the main difference between lisp-1 and lisp-2 (or lisp-n) is going to be how clean your code looks when you lean into the FP style. In a lisp-2 you'll need to do something like this:

  (defun apply-twice (f x)
    (funcall f (funcall f x)))

  (apply-twice #'1+ 2)
Versus this with a lisp-1:

  (define (apply-twice f x)
    (f (f x))

  (apply-twice 1+ 2) ;; assuming 1+ is defined
But there are so many other differences between the lisps in the two categories that this probably won't be the deciding factor for most people.
wk_endtoday at 5:47 PM

The argument is: if you don’t have hygienic macros, a Lisp-2 is going to be less brittle than a Lisp-1.

The classic example is, imagine you have a function with a local variable called “list”, common enough. Now imagine you invoke a macro inside that function which generates a call to the built-in “list” function - also common enough. In a Lisp-1 without hygiene that breaks - your local definition shadowed the built-in; in a Lisp-2 or hygienic Lisp-1 you’re in the clear.

show 2 replies
jwrtoday at 5:03 PM

As someone who has used both kinds over many, many years: it really doesn't matter.

nathan_comptontoday at 6:33 PM

I am a strong proponent of Lisp 1, primarily because the distinction between functions and other types of values is artificial. Functions have first class semantics in Lisp 1 and Lisp 2, but Lisp 2 makes you denote them differently but in an inconsistent manner.

Lisp 2 advocates typically make a few arguments. One is that having a separate namespace for functions makes it clearer when you are using a function vs another value. The second is that the evaluator has less work to do when examining the head of a list - it needs only look in the function environment, not the full environment.

On the first subject I must disagree - you can bind a function to a regular variable and then use that variable everywhere (except in the car of a list representing a function call), so for most positions in a set of expressions you don't really get information about whether the object being denoted is a function or not.

I suppose the second point is somewhat valid, though I suspect if you benchmarked interpreters and compilers it would barely matter. As a person who favors functional programming with a lot of combinators, I find Lisp 2 introduces a lot of pointless noise in the syntax for no reason. And I fundamentally just don't see functions as significantly different sorts of values, so I find the syntactic distinction bizarre.

dismalaftoday at 4:56 PM

IMO if we look at Lisps today the question looks more like: SBCL, Chez Scheme, Racket or Clojure.

Common Lisp and Racket are Lisp-2s but honestly, the namespace thing seems like a minor difference compared to all the other features that differentiate them.

show 1 reply