Impractical, Uncommon Lisp.
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.