Casting SPELs in Lisp

A short and sweet Lisp tutorial that has the courage to introduce macros to absolute beginners.

The reader is shown how to build a simple text adventure game using Lisp. The code is available for download.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Lisp for the 21st century?

You may be wondering why the command is called setf... I'm not sure why, actually, but you'll find that a lot of the commands in Lisp have quirky names, since Lisp is such an ancient language.

Has anyone ever created a lisp variation that tried to remedy some of this 'quirkiness'? Maybe changing 'car' and 'cdr' to something a little less obtuse, like "head" and "tail" or "first" and "rest" for example?

Is syntax the problem?

Does it really matter? I'm not sure that these quirky names are the main obstacle for lisp in the 21st century.

A few years ago you heard a lot of people saying they would never use Python because of this whitespace thing, now that it's more widespread and accepted, you don't hear it that often.

To say it in a diferent way: I once read someone asking how it was for non-native English speakers to program with "english" words, I always thought it was easier because this way you don't confuse the meaning of a word in the programming language and in "real life".

To keep this post on-topic: math is hard, but humor is harder.

Whitespace is different

A few years ago you heard a lot of people saying they would never use Python because of this whitespace thing, now that it's more widespread and accepted, you don't hear it that often.

To be fair, the whitespace issue is a little different. Experienced programmers didn't like it because they thought it was a bad thing to do (probably trying too hard to reason about it instead of just using it). When people came around, it wasn't simply because they got used to it; they just realized that it doesn't suck (or doesn't suck enough to get in the way).

Though you can get used to "car", "cdr", and "setf", it is still an unnecessary obstacle for beginners (small as it is). Of course, there are other things about Lisp that are more serious obstacles. This tutorial does some things very well, but once it gets to the "describe-paths" function, I don't see how newbies could keep up.

PAIP

Peter Norvig avoids car in cdr in Paradigms of AI Programming.

how to design programs

...seem to use "first" and "rest" to teach scheme..

Greg Buchholz: Has anyone eve

Greg Buchholz: Has anyone ever created a lisp variation that tried to remedy some of this 'quirkiness'? Maybe changing 'car' and 'cdr' to something a little less obtuse, like "head" and "tail" or "first" and "rest" for example?

You mean like Common Lisp?

Obligatory Lisp fan response

car and cdr are composable, ie caar, cadr, etc. head and tail are not.

is there anything

like:

(item some-list 5) ; get element 5 (6th in there)
(item some-list -1) ; get the last element
(items some-list 2 4) ; get a list of the 3rd to 5th items

in any of the LISPy languages?

(All zero-indexed of course :-) )

Re: is there anything like...

(item some-list 5): (nth 5 some-list) or (elt some-list 5) [elt also works on vectors (1-dimensional arrays)]

(item some-list -1): (first (last some-list)) or (first (last some-list 1)) [(first (last some-list 2)) gets the second last element]

(items some-list 2 4): (subseq some-list 2 4) [also works on vectors]

That would be Common Lisp.

yeah, but

if you're using caar, caaadar, and so on, you probably would be better off defining helper functions (if only for legibility). In my own programming I take any use of caar or cadar or whatever as a sign that I need to rethink my data.

And that's an advantage of us

And that's an advantage of using them, I think. You can later shift over into using OOP or whatever, after using cxxxr to make a quick sketch.

A lot of things are like that, such as structs, which people might naively think of as crappy objects. In fact, I just wrote a tax program last week, and there's a special feature of structs where you can give names to items in a list. So instead of cadr or second, I could refer to the second item in a data list as price.

[edit: I was unclear in describing the struct feature.]

Replacements for car and cdr

That's a typical newbie question. There's first and rest in Common Lisp. However, the advantage of car and cdr is that they do not tell you anything about an intended meaning. The basic data type of Lisp is not the list, but the cons cell, and car and cdr allow you to access the one or the other element of a cons cell. It's up to you what specific meaning this has in a concrete setting. Other names, like first/rest or head/tail can be too suggestive. Neutral names are very useful during exploration when you don't know yet what your code will end up like.

You can.

First and Rest are both trivial to define and in the standard. But then, does it really matter? I doubt the mnemonic value of commonly-used constructs is that important.

Say what?

I don't understand how you can believe this. Take your favorite programming language, and rename all the keywords like so:

lambda -> balloon
define -> parakeet
defmacro -> slurp

Then translate a small program into this new language, and show both it and the original to someone unfamiliar with programming. See which they prefer.

I think of this as a UI issue

I think of this as a UI issue, therefore you might want to actually test how bad this UI decision is on real people. A salient point is that car/cdr is internally consistent; you can compose them, a comes before d, etc. So my guess would be it's no big deal.

Now, for a Lisp UI nightmare, let's look at lambda. From Kent Pitman's interview [and here's part 2]:

"After trying to 'self-learn' lisp in the 80's I get this physical reaction to the word 'lambda'...a cold sweat combined with the involuntary retraction of my testicles to a protected location in my abdomen (damn unpleasant shit)...I usually avoid that second one by mentally going through the mechanics of 'hello world' in C, or any half-a-dozen other programming languages."

Unfortunately, many are of the opinion that lambda is exclusionary and arrogant, especially with the related term "lambda calculus." In fact, your suggestion that lambda -> balloon is very close to what I've personally wished, that it was called something like "bubble". A lexical-bubble.

And similar to what you suggest, the Casting SPELs in Lisp article recommends defmacro -> defspel.

The canonical pet peeve among Lisp users is the occasional inconsistent argument order. elt/nth. Intellisense solves it, but why leave it to intellisense?

Improving on car/cdr

OK, car/cdr might not be too bad, but they can be improved. Maybe renaming them to c0/c1. That would keep the advantages of car/cdr, but they appear more low level (and cannot be mistaken for a vehicle). It might also be an advantage that the compositions give a binary number.

Amusing

Actually the words you used prove the opposite of what you intended to show. What the heck does "lambda" mean to anyone? It's just a symbol that was accidentally used, and whose name became a keyword in Scheme. Might just as well have been "omega" or, for that matter, "ballon".

how about 'anon' or rather th

how about 'anon' or rather than 'lambda'? A bit more clear I think.

Perception bias

Using 'anon' focuses on a feature which isn't even a property of lambdas themselves. When we create an object in an OO language, but use it inline rather than assigning it to a variable, we don't usually focus on the fact that this is an "anonymous" object. Whether or not it is assigned to a variable is not an intrinsic property of the object itself.

Exactly the same thing applies to so-called "anonymous" functions. The "anonymous" aspect isn't even a property of the function. The term is only really used to contrast with languages which don't treat procedures as values.

Javascript uses the keyword "function" to define lambdas; Perl uses "sub". In both cases, these define first-class values which close over their lexical environments. Either of these terms are probably more familiar to most programmers (although "sub" seems rather retro and BASIC-like to me). However, neither term differentiates the named entities from less powerful constructs which exist in other languages.

Ideally, what's needed is a term which describes the unique characteristics such as lexical closure and the ability to be treated as a value. Luckily, there's already a well-defined, widely accepted term for such constructs. That term is "lambda".

Of course, none of this negates the "marketing" reasons for compromising and diluting the terminology anyway. We just shouldn't forget that we're deliberately ignoring the only term that's specifically defined to refer to the constructs in question.

Reminds me..

of Why's (Poignant) Guide to Ruby (previously discussed here). For the pictures, humor and "for the uter newbie" feel, mostly. The story isn't as distracting, which might be a good thing.

(grr, hit enter on subject li

(grr, hit enter on subject line. Notes to LtU admins - editing a null comment appears to not work.)

One nice thing about car and cdr (and their composites) is that you can pronounce them. The CLHS even tells you how (search for "Pronunciation").

"see zero", "see one", and "see one one one zero" just seem like mouthfuls to me. I don't know about you, but I like to be able to talk about code.

(Really, I don't see what the big deal is. I mean, does '^' make sense for XOR in C? Or '%' for MOD for that matter?)

Pronounceable?

If pronunciation matters, then clearly "wakka" and "chikka" are the only sensible choice (see here).

Heh. :)

Heh. :)

Yay!

I like how the Lisp compiler is personified as a cute green blob!