75 Posts Tagged 'Lisp' RSS

Practical Common Lisp (review)

My current "programming language of the week" is Common Lisp. I got a dead-tree hard copy of Practical Common Lisp as a going-away present from my last job. This week on a trip to Eugene, Oregon (as part of the process of getting my NEXT job, hopefully) I had lots of time to read through it. I "finished" it today, for some definition of "finish" which includes a "skipped over large chunks of chapters that were way over my head" clause.

I was amazed to learn from Peter Seibel's blog that as of May 2007, there were less than 10,000 copies sold. I think I am really clouded in my view of what kinds of things people know in the world at large. I know there must be some overwhelmingly large group of Windows-only programmers who only know C# and/or Java and nothing else, but perhaps because I live in the world of Linux and open source, I never come in contact with them. When I look around me (figuratively, online) I see Linux guys who know Linux and Perl and Ruby and *nix-style C++ and whatnot. So I often find it very difficult to extrapolate anything about the world at large based on what I see around me.

Either way, PCL is a good book. It has an immense amount of information in it. Almost overwhelmingly large amounts of information, somehow. It may be overwhelming simply because of how unfamiliar many of the concepts and terminologies are to one such as myself who doesn't come from a Lisp background. But there are also many things that I'm 100% sure I wouldn't understand at all if I didn't already know Ruby pretty well (largely because Ruby ganked so much stuff from Lisp). If I didn't have a Ruby background, I'd be even more lost than I was.

Whether Lisp is really practical or not, I'm not sure. For example, it takes a lot of housekeeping even to get a Lisp environment set up. Thankfully available on Peter's website is a pre-packaged "Lisp in a Box" that can at least get you to a REPL prompt with no effort. But then you have to start writing code. Lisp code can be compiled, or interpreted, or a combination of both(?), or both simultaneously(?). Or it can be typed manually into the REPL, and then run, or compiled, or dumped to a file. Or you can dump an image of the Lisp instance (image?) to file entirely. Often there's a mess of manual dependency-managing any time you use packages. And then there are special things you need to do to make sure certain kinds of macros and things load correctly when compiled and run from compiled form, or when saved to file in "readable" form and then re-read as lisp code at a later time. And there are certain things in Lisp that can't be output in "readable" format at all. Do I sound confused? I surely am. I found this writeup showing how one person gets started on a Lisp project, which is somewhat helpful.

Yeah, you can get SLIME for Emacs and then start banging away in the REPL, but losing everything when you close it isn't a lot of fun. So I'm getting by with typing stuff into an Emacs buffer and manually running top-level forms one at a time via a bunch of Emacs shortcuts. It still seems like I'm doing a lot of the work that my environment should be doing for me. But I suppose it's no worse than trying to set up a bunch of Makefiles to manage C++ code. And much of my trouble seems to be a product of my inexperience (but that can probably be said of anything).

Lisp does have a lot of things that are really interesting, like multi-methods and of course macros, which the book covers in a wonderful amount of detail. Even the exception/condition system is different (and arguably much more powerful) than other languages'. The Lisp language itself is simply more powerful than most other languages in many ways, is the only conclusion I can come to. It's more extensible and it gives you more options for abstracting things in ways that are impossible to do (easily) in other languages due to the syntax and available constructs the languages provide. At the same time, all this power comes at the expense of code that's nearly unreadable by my somewhat biased standards; nasty Perl-esque punctuation abounds, there are many inconsistencies in how things are called or passed parameters (often for "historical reasons", the bane of my existence), and given the ability of macros to drastically alter the way code looks and works and to define mini-languages inside Lisp itself, you're very often not quite sure what exactly you're looking at at any given moment.

But I highly recommend the book. For non-Lispers like myself, if nothing else it gives you a taste of language that's very different from probably anything you've seen before, and it can point you in many interesting directions you may never have thought possible. On the other hand, is Lisp a revolutionary Zen-like enlightenment-producing revelation of a language which will expand your programmer mind into vast new dimensions of coding efficiency and bliss? I have yet to take sip of the Kool-Aid required to answer that question, but who knows.

September 18, 2007 @ 7:24 AM PDT
Cateogory: Programming
Tags: Lisp, SLIME, Emacs

Ow, my brains. (DRY)

At work I was faced with dumping out some reports of some stuff. No big deal, Ruby to the rescue. I have a huge array of lines of data and I need to select out a few bits and output them, doing some simple manipulation to it in the process. So I ended up with something like:

File.open('some_filename', 'w') do |f|
    f.write lines.sort{|a,b| a[0] <=> b[0]}.select{|a| a[0] < 50000}.collect{|a| a[1]}
end

But it turns out I need to do this multiple times. Each time I do it, it will have a different filename AND a different select criteria. Changing the filename is easy; just make an array of strings and iterate over it.

But how to change the select criteria? If it was something easy, say I always wanted all the data < X for various values of X, then it would be simple to code; just pass in X as a parameter. But say I want the data greater than X in one file and the data less than Y in another file? Or maybe a third report with values == Z. Or who knows what else. Now it's not just data varying; the logic varies also.

A few years ago I'd probably have copy/pasted all the code and just changed the little bit in the select block, like a goon, and rightly suffered for it. But Ruby lets you assign blocks to variables. Then you can send the block to an iterator using &block:

[ ['one_filename', lambda{|a| a[0] < 50000}], ['another_filename', lambda{|a| a[0] > 70000}]].each do |fn, test|
    File.open(fn, 'w') do |f|
        f.write lines.sort{|a,b| a[0] <=> b[0]}.select(&test).collect{|a| a[1]}
    end
end

It's funny how the code is simultaneously shorter AND better AND more powerful than it would be copy/pasting or using some other method. I remember reading in a Lisp book that this is often a sign that the code is good. It's essentially the DRY principle at work.

This kind of programming is very "emotionally satisfying", but at the same time it's often very hard to wrap my head around. It took me a while to figure out that the above is what I wanted, and to realize that Ruby was capable of it.

I remember very well when I was just learning QBASIC 10+ years ago in high school, this is exactly the kind of thing I always WANTED to do. I have variables; let me use variables to vary EVERYTHING, data and logic and code, everything. I couldn't do it then, obviously. If only I'd have picked Lisp instead of BASIC. Now I feel like I'm kind of re-learning or un-learning all the limitations of the iterative, clunky ways of thinking of programming that were so ingrained by college and years of C/C++. (I remember a professor saying that function pointers in C++ are "scary things, and probably too advanced for this class to cover".)

February 01, 2007 @ 7:11 AM PST
Cateogory: Programming
Tags: Lisp, Ruby

Lisp, part 2

Everyone I know who does Lisp says "Learn Lisp and it will change how you look at all other programming languages!" I don't know if that's true or not, but I think I'm starting to learn a bit.

August 13, 2006 @ 5:22 PM PDT
Cateogory: Programming
Tags: PCL, Lisp, PHP, Perl, Ruby, Books

Baby steps

My first pathetic program in lisp:

(defun fib (x) 
  (if (and (not (equal x 1)) (not (equal x 0))) 
    (+ (fib (- x 1)) (fib (- x 2))) 1))

Try not to be too intimidated by the complexity or sheer or power of it.

August 11, 2006 @ 4:44 PM PDT
Cateogory: Programming
Tags: Lisp

Lisp?

I decided to start learning Lisp, after hearing good things about it from a bunch of people. So far, I can recognize a lot of Ruby elements that must have been ganked from Lisp. My prediction is that Ruby will end up being mostly a superset of Lisp except for a few areas Lisp is specifically targetted at. But we'll see.

I'm learning right now via the book Practical Common Lisp. The whole thing is free online, which is clearly awesome. I may buy it just so I can read it when I'm away from my computer.

As the book says, finding a Lisp interpreter isn't straightforward, because there are a lot of them. I settled on SBCL, for the simple reason that it's the only one that would compile properly. If you use Gentoo and want SBCL, be sure to get the unstable version. The stable version wouldn't even compile for me.

I'm resisting the push to use emacs instead of vim. I'll stop using vim when you pry it from my cold, dead hands.

August 11, 2006 @ 11:31 AM PDT
Cateogory: Programming