A friend of mine, Rob Ahrens, asked me how my learning of the
programming language Lisp was going. I thought I’d respond in an open
Um, Hi, Rob.
I have two previous posts on lisp, [A programming language only a mother could love][blog1], and [lisp, the beautiful hydra][blog2].
When I’ve had time, I’ve been attempting the problems in [Project
Euler][pe]. Euler lays out a series of ~200 mathsy programming
puzzles, things like ‘find the sum of all the even-valued terms in the
Fibonacci sequence which do not exceed one million.’ I’m using them as
a way of trying out the language. At my side, possibly the only decent
beginner’s book, [Practical Common Lisp][pcl]. (It’s also free.)
So far, I’ve finished 2 problems. Hmm. I’m pretty sure I could have
finished more of them, more quickly, in almost any other language.
That, I think, is at least in part that lisp doesn’t come naturally if
you’re used to non-lisp languages, things that bear a resemblance to C
or BASIC. I’m having to go right back to basics, learning to construct
things in a new way. Here’s the code I used to solve problem 2;
(defun fibseq (max)
(let ((result ())
(setf term (cond ((= i 0) 1)
((= i 1) 1)
(T (+ n-1 n-2))))
(setf n-2 n-1)
(setf n-1 term)
(setf i (1+ i))
(when (> term max) (return))
(push term result))
(defparameter allfib (fibseq 1000000))
(defparameter evenfib (remove-if-not #’evenp allfib))
; the answer!
(print (reduce #’+ evenfib))
I don’t print this here to demonstrate the clarity of lisp. In fact,
the opposite. This looks like hell to me, at least right now. There
is, no doubt, a *far* better way to do this. But I don’t know, and so
I’m writing programs that are terribly inelegant. Nestled in the code
above is a non-terminating loop with a break condition, because I
couldn’t figure out how to do the equivalent of
while (n < 1000000)
Right now I feel like I did when I was ten, programming in BBC basic
and using GOTOs. Hell, it knocks together working programs, right? But
you don't want to stay there too long. That feeling of childhood
programming, though… there's something compelling in it. Lisp tastes
of nostalgia. Remember programming Logo? Or BASIC? Lisp is making me
feel like that. At least for now.
Pretty soon, I hope to have mastered basic loops. Then I'll be well on
(setq *subject* (list '( ')))
Or, now I will talk about parentheses.
In my head, despite being entirely uncomfortable with `while` loops,
I'm starting to see everything falling into a lisp syntax. The idea of
just bracketing up your stuff into lists seems like a great
first-draft syntax for *everything* — want to talk about data
(entity1 (attribute1 attribute2))
(entity2 (attribute3 attriubte4)))
want to write pseudocode for a function call?
(func (param1 param2) …)
want to write a todo list?
(tidy (kitchen living-room bathroom))
Valentines day coming up?
(make-list #'(lambda (i thee)
(permute #'love i thee))))
Ok. Maybe not. (apologies to Elizabeth Browning there.)
But you get my point. I hope. Those brackets are just fine for
*everything*. I'm starting to understand why hardcore lispers want to
do everything in lisp. My brain is infected with brackets.
But for right now? I'm going to learn to do a `for` loop, and then