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][blog1], and [lisp, the beautiful hydra][blog2].

[blog1]: http:2007/04/02/a-programming-language-only-a-mother-could-love/
[blog2]: http:2008/01/21/lisp-the-beautiful-hydra/

Childhood Nightmares
——————–

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 ())
(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.

[pe]: http://projecteuler.net/
[pcl]: http://www.gigamonkeys.com/book/

Advertisement

2 responses to “Impractical, Uncommon Lisp.”

  1. The links to the two previous posts are malformed, but can be recovered by removing the characters from the start of the first date until right before the start of the second.

  2. Assuming the author has continued his Lisp exploration, he no doubt knows this already. For others who may not, Common Lisp includes a “while” construct: (while TEST BODY...), which does pretty much what you’d expect; where in C you might

    int i = 0;
    while (i < 10) {
    i += 1;
    printf("i equals %d\n", i);
    }

    in Common Lisp you could just as well

    (let ((i 0))
    (while (< i 10)
    (setf i (1+ i))
    (format t "i equals ~a~%" i)))

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: