The Lisp Language
Time to get sadistic again!
When the Pink Floyd rock-opera movie “The Wall” came out, a rumor circulated that you couldn’t understand the movie without dosing up on LSD, and then, allegedly, the whole movie would come together and make sense in a new way. Now, I’m not advocating drugs for understanding Lisp… but this is one language where I wouldn’t rule it out!
Which is not to say that it’s a bad language; in fact, it is quite good. It is also the original high-level scripting language, to which Python, Perl, Ruby, Scheme, Haskell, and dozens of other languages owe a debt. But for the novice programmer, Lisp comes with a host of handicaps right out of the gate:
- It is utterly alien. If it came to light that Lisp was actually created by an alien intelligence from a distant galaxy, nobody would be surprised.
- It is very old. It started out in 1958, running on PDP machines. It has a heritage from a time when only people with Computer Science degrees could get in the lab to touch a computer. It is also designed as a direct implementation of the ideas of “lambda calculus”, itself no easy concept for a novice to grasp.
- There is no standard! There are different dialects of Lisp numbering close to the hundreds, each one incompatible with the others. Stanford Lisp, MACLISP, InterLisp, ANSI Lisp, Common Lisp, Emacs Lisp, GNU CLisp, Steel Bank Common Lisp… that’s just the tip. None of these are more common than the other, and good luck finding documentation about half of them.
- The language community is deeply fragmented and tiny. Each dialect has 50 zealots clinging to it, loudly flaming each other in forums, fighting to have their favorite flavor of Lisp declared the standard. Lisp’s roots go way back in computer science, and let’s just let it be said that elderly computing professors aren’t known for being generously accepting of new ideas.
- It isn’t widely deployed. The greatest current usage of Lisp shows up either as the language you control the Emacs editor in, or Scheme, the Lisp sub-set used to create macro scripts in Gimp (called “script-fu”).
- It is quirky. For instance, the concept of a linked list is wrapped up in the notion of “cons cells”. Accessing the first element of a list of cons cells is a “car”, and the rest of the list is a “cdr”. This will make no sense to you if you don’t know that “car” and “cdr” stand for “contents of the address register” and “contents of the decrement register”, which were originally two assembly-language macros on the now-long-dead IBM 704. Some versions still use car and cdr, some versions have updated to instructions like “first” and “next”, some versions keep both, some versions fly off and invent their own new syntax…
Nevertheless, Lisp has its supporters. Eric S. Raymond has cited the value of learning Lisp this way: “LISP is worth learning for a different reason – the profound enlightenment experience you will have when you finally get it. That experience will make you a better programmer for the rest of your days, even if you never actually use LISP itself a lot.” And then there’s Paul Graham, who made a killing writing software in Lisp and now is a prominent voice in the technology start-up community, and who has almost single-handedly kept Lisp in the spotlight.
Finally, Lisp, for all its weird syntax, is somehow… beautiful. Lisp code reads like a Zen haiku. Lisp is called “the programmable programming language”. It is efficient and compact and consistent within itself.
But let’s start Lisping! I’m picking eLisp, the Emacs implementation of Lisp, because (a) it is cross-platform and widely deployed, and (b) if you learn eLisp, you will at least have the practical application of writing Emacs editing modes, so you can put it to use right away. But Emacs Lisp isn’t better or worse then any other Lisp.
Two things to know about Lisp syntax. 1. It’s white-space indifferent. 2. It has lots and lots and lots of parenthesis. Some people hate that.
;; All comments begin with a double semi-colon. That's all!
(setq part-number 81)
(setq percentage 33.3)
(setq address "345 Notareel Street")
(setq colors '(orange green blue))
Really, “setq” is an abbreviation for “set quote”. The quote is to tell it that this is a variable name here, so it doesn’t try to evaluate “part-number” as a function. You could also say:
(set 'colors '(orange green blue))
and be just as right.
(message "What kind of data do you call this?")
(progn (setq animal "frog")(print animal))
The second line uses “progn” to link a series of functions together to execute them all at once.
(setq age (read-string "Enter your age:"))
Just type in your number here and it’s in the variable ‘age’.
(/ 99.0 2.0)
(* 2 2 2)
(setq result (+ 5 (- 10 5)))
(insert-file-contents "~/code/flash/flash_test.html" nil 0 500)
This will snarf the first 500 characters of the file and dump it into the current buffer.
(if (or (= x 1)(> x y))(print "yes"))
Translation: “If x is equal to one or x is greater than y, print yes.”
(setq loop 0)
(while (< loop 100)
(princ (format "Thank you, may I have another?"))
(setq loop (+ 1 loop)))
Now, why aren’t we using “for”? Well, the “for” syntax in other languages is actually just a short-hand for “while” anyway, so… eLisp doesn’t have a “for”. You could build your own if you wanted to. “princ” is actually not a typo, the function prints the output in the return value buffer.
(while (or (not (= feeling "seasick"))(not (= action "barfing")))
Let’s stop here and talk about “inside out evaluation”. First, take (= feeling “seasick”), which can evaluate to “t” or “nil” (yes or no). Then take (= action “barfing”), which can evaluate also to “t” or “nil”. Now slap a “not” on the outside of each, which reverses the output of the evaluation (we’re checking to make sure that the conditions are false). Then we put them both inside an “or” conditional, which will evaluate to “t” as long as one or the other condition is true (it’s true that it’s false), but evaluate to “nil” if they are both false. “Spin” I just made up, it could be a function we declared previously.
You are not expected to understand this. Neither am I.
Are required with
Just like “import” in Python.
(defun factorial (n)
(if (<= n 1) 1 (* n (factorial (- n 1)))))
“Defun” is “define function”. We have created a function that will take one numeric argument and return its factorial. The result of the following two lines are equal:
(* 1 2 3 4 5 6 7 8 9 10)
We could go on… but let’s move along to other scripting languages, before we forget how to talk in normal English. If you want to explore Lisp further, you can also pick up CLisp for any platform. That’s another place that’s just as good to start as any other.
- Lisp is as Popular as Harry Potter?
- The PHP Programming Language
- Shell Programming
- The Awk Programming Language
- The C Language