For the last few days, I’ve been trying to get my head around Common Lisp. Here are my first impressions.
It’s a language that is both incredibly beautiful and awfully ugly. I don’t know quite how it manages it. First, some of the ugly;
(apply
#'(lambda (x y) (+ x y))
‘(1 2))
See? Ugly. (The code is from Paul Graham’s free book, [On Lisp][].) It calculates the same as this C code;
return 1 + 2;
But, of course, all that `#'(lambda` stuff is doing more than the C; in fact, it’s doing more than C possibly can, which is where the beauty comes in.
It seems to me that Lisp has some fantastic fundamental ideas and some really awful choices in naming and syntax. For example, here’s the way you set a variable in the lisp console;
CL-USER> (setq x 4)
4
`setq`! not `:=`, not `assign`, not `set`; `setq`. That’s why I mean by awful naming.
Another; here’s how to get the first item in a list;
(car list)
again, `car`? Admittedly, you _could_ use `first`, which is much more sensible, but the Lisp world seems to have settled on `car`, which stands for the ‘contents of the address register’, referring to a memory register in a long-dead machine from the 1970s. Awful naming.
However, the punctuation is great. It’s just that all the words suck.
If I were an author, and an editor gave me that advice, I’d quit. Wouldn’t you? So tell me something. Why is it that Lisp’s punctuation seems to hold the most profound and important programming concepts?
For example; the quote character — ‘ — allows you to freeze-dry code into something you can pass around like any other variable. If I want to multiply a global variable, x, by two, I’d say this;
CL-USER> (setq x 2)
2
CL-USER> (* x 2)
4
Thats sort-of-equivalent to this c-like code;
int x = 2;
int doublex = x * 2;
But now I’m going to use the quote symbol…
CL-USER> (setq x 2)
2
CL-USER> (setq doublex ‘(* x 2))
(* X 2)
CL-USER> (eval doublex)
4
I set the global variable `x` to 2. Then I set the variable `doublex` to be a piece of code which doubles the current value of `x`. Then, I evaluate the code in `doublex`, which gives me four.
The fun part is, you can’t do this in C — I’ve assigned arbitrary code to a variable. So now I can pass functions around like variables. Isn’t that just like function pointers in C? A little. But Lisp goes way beyond.
The awful glory is that the code is just a list; it’s the three symbols `*`, `x` and `2`. And since lisp can edit lists, and programs are lists, lisp can edit programs. And it’s no trickier to edit programs than it is to change arrays.
I’ll say that again. _Lisp programs can edit programs as easily as C can edit arrays._
Watch this. I’m going to examine code to see if it’s a multiplication.
;; `x` is a multiplier if it starts with the `*` symbol
(defun is-multiplier? (x)
(eq (first x) ‘*))
;; is doublex a multiplier? returns true.
(is-multiplier? doublex)
Just by checking for the `*` symbol, I can tell you things about the code.
And if we decided that we actually wanted to calculate x+2, rather than x*2? Well, we just change a piece of the program
;; change the first item in ‘doublex’ to a plus.
(setf (first doublex) ‘+)
This is stuff you just can’t do in other languages. I’m going to keep looking into Lisp. It seems worthwhile.
[On Lisp]: http://www.paulgraham.com/onlisp.html