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
letter.
Um, Hi, Rob.
I have two previous posts on lisp, A programming language only a mother could love, and lisp, the beautiful hydra.
Childhood Nightmares
When I’ve had time, I’ve been attempting the problems in Project
Euler. 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. (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 ())
(n-1 1)
(n-2 0)
(term 0)
(i 0))
(loop
(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))
(print result)
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
my way.
(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
structures? write
(data
(entity1 (attribute1 attribute2))
(entity2 (attribute3 attriubte4)))
want to write pseudocode for a function call?
(func (param1 param2) ...)
want to write a todo list?
(do
(buy bread)
(tidy (kitchen living-room bathroom))
(get life))
Valentines day coming up?
(get-count
(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
we’ll see.