Hacker News new | past | comments | ask | show | jobs | submit login

If empty list isn't "falsey", it's not Lisp. It's a "Lisp-like" at best.

Sussman and Steele had the good sense not to call Scheme "<something> Lisp", because they knew that it would "ring falsey".




could you produce an exhaustive list of properties of a proper Lisp so that i don't mistakenly call something that isn't a Lisp, a Lisp?


Yes, I could. Though I would avoid using proper; the aim isn't to deem something "good" or "bad", just whether a name applies to it. An "improper" Lisp is very good and proper something else, and perhaps very Lisp-like language with a lot of conceptual compatibility with Lisp.

In a Lisp:

* expressions evaluate their sub-expressions strictly, usually in a left-to-right order unless otherwise noted (in the case of control constructs which repeat or omit the evaluation of some parts, and such).

* evaluation of all expressions either always produces a value, or in he case of multiple value support, always produces a tuple of zero or more values. In any case, when an expression appears in a spot where its value is required, its first value is taken, and if it returns no values, its result is taken to be nil.

* Tokens consisting of nothing but the 26 upper and lower case letters denote interned symbols. Two symbols nil and t are special in that when the are used as expressions, they evaluate to themselves and may not be used as variable names. Symbol names may be case-insensitive/folding so that NIL and nil denote the same object.

* A type exists called a cons cell (or just "cons") representing a pair of values bound together. It is produced by a two-place function called cons which creates a cons and initializes its two fields from those two arguments. The left argument initializes a field called car, and the right argument initializes a field called cdr.

* A pair of unary functions car and cdr take a cons cell argument, and retrieve the car and cdr field, respectively. car and cdr may also be applied to nil, and return nil.

* Cons cells are mutable, except possibly cons cells derived from literals expressed in program source code (for the sake of being able to put compiled program images in read-only memory, and condense their representation by collapsing identical conses). The functions rplaca and rplacd mutate the car and cdr of a cons.

* The printed notation for a cons cell is (a . d) where a recursively denotes the printed notation for whatever object constitutes the car, and likewise d is the printed notation of the cell's cdr. In the special case when d is the object nil, the (a . nil) notation condenses to just (a) which is understood to be equivalent.

* Lists are represented by cdr-recursive chains of cons cells: a list is zero or more conses, referentially linked via cdr fields, with the car fields used for the containment of the list elements. The symbol nil appearing in the cdr of a cell indicates the end of the list. A cons cell appearing in the cdr of a cons cell indicates that the list continues. A value other than nil or a cons cell also terminates the list, but "improperly": the list as a whole is called an "improper list".

* The symbol nil by itself represents the empty list. There is no "improper empty list": a non-empty list begins with a cons cell. (In some situations, there is an "emergent phenomenon" in which a non-nil atom behaves as an empty improper list; e.g. (append '(1) 3) -> (1 . 3).

* The symbol nil also denotes the (one and only) Boolean false value. A form which returns a Boolean indication returns nil to indicate "false", and any other value to indicate "true". The symbol t is a canonicalized representation of truth.

* Every object which is not a cons cell is an "atom". The consp function returns t (true) when its argument is a cons cell, otherwise nil. Its logical opposite is the atom function which returns t for an atom, and nil for a cons cell.

* A Lisp supports the functions and operators: null, and, or, cond, eq, equal, apply, eval, quote, cons, car, cdr, rplaca, rplacd, list, append, lambda and let.


strikes me as a detailed description of a very particular implementation that you specifically like. considering lisp is a family of languages - which of these rules do you accept deviations from and by how much?


> detailed description

Hardly at all; even the 1960 Lisp 1 manual ran for some 160 pages; this is just a few bullet points. It leaves a lot of room for family inclusion.

But not every Tom, Dick or Harry that walks in off the street is your family member, or even a friend.

> very particular implementation

Nope; just the original thing and many of its derivatives that can legitimately be called some kind of Lisp.

"Lisp" is in fact the name for a particular set of implementation features.

You may have a very nice implementation of some sort of list processing with all the equivalent expressivity and power, or whatever measure of pedigree we choose; it's just not Lisp: pick another word.

> which of these rules do you accept deviations from and by how much?

None. These are the things someone shouldn't mess with, if they want people to refer to their programming language as a Lisp dialect.

And, in fact, at least if we look at major works in the mainstream, most of those who do change those things understand this and don't use that term in naming their language. So, a fairly good approximation to the predicate "is not Lisp" is "does not have 'Lisp' in its name".


> that you specifically like

Also false. The requirements could be implemented by something I strongly dislike. For instance, someone's crappy one-weekend Lisp dialect, hopelessly unsuitable for real work, in which an error stops the entire process without leaving a clue where it occurred. I will certainly prefer a quality Lisp-resembling language to such a thing.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: