Archive for July, 2007

Closures + Hash Tables = As Much OOP as You’ll Ever Need

July 9, 2007

“In another thirty years people will laugh at anyone who tries to invent a language without closures, just as they’ll laugh now at anyone who tries to invent a language without recursion.” — Mark Jason Dominus

You might be wondering what all of the talk about closures is about, really. You might be scratching your head at the boring examples that just run a simple little counter inside a function. You might be wondering how functional programming can be more fundamental than (and even able to subsume) object oriented programming. You might be disappointed that Mark Jason Dominus hasn’t gotten his book up on-line, yet. You might be willing to settle for a quick dumb example in Common Lisp written by an average developer. If any of the previous guesses are right, you came to the right place.

In this text file, you’ll find a mere 16 13 lines of code that define a small chunk of OOP in Common Lisp. The code should not only be understandable to beginners, but it was actually written by a beginner– so it should also hopefully give an indication of how easy it is to build “new” fundamental-ish programming concepts onto Common Lisp.

An “obi,” as I define it here, is somewhat like an object, but there are some key differences. (I call my version of an object an “obi” because I’m implementing just a very small piece of OOP.) An “obi” is a hash table wrapped up in a closure. The closure provides one of the main pillars of OOP: encapsulation. Nothing in your program can mess with the variables inside of closure without interacting through the function call that the closure provides. The hash table provides a place to store all of your properties and methods. Because Lisp is dynamically typed and because functions are first-class objects, there’s really no need to make a difference between properties and methods. In an “obi,” functions are just one of the many information types that can be stored in the hash table.

In the example below, we see an obi being used from the REPL prompt. Its color and shape properties are set and also a function called add is put in and called. The “.” is used in Common Lisp to notate a dotted list, so I used ~ to represent “get”, ~> to represent the create/set a property/method, and ~! is used to represent a call to an obi’s function:

; SLIME: The Superior Lisp Interaction Mode for Emacs
CL-USER> (setf f (create-obi))
#<COMPILED-CLOSURE CREATE-OBI-1>
CL-USER> (~> f ‘color ‘red)
RED
CL-USER> (~> f ‘shape ‘square)
SQUARE
CL-USER> (~ f ‘color)
RED
T
CL-USER> (~ f ‘shape)
SQUARE
T
CL-USER> (~> f ‘add #’+)
#<SYSTEM-FUNCTION +>
CL-USER> (~! f ‘add ‘(1 2 3 4 5 6 7))
28

Obi’s lack any form of “type”– in fact, you can add additional properties and methods to them at any time. Even if you don’t intend to use Common Lisp in a production application, this is an option that should be in your mental tool box. You may not always need to resort to using inheritance or subclassing to create a variation of an object you defined. If you think a little bit more functionally, you can abstract out the bulk of the design and then allow other developers to customize its use by setting or overriding some of the key functions. Of course, in a wide-open typeless setting, that’s a feature you get whether you think you want it or not!

For a much more elegant and substantive example of how to implement OOP in Common Lisp with an insanely small amount of code, see Paul Graham’s Ansi Common Lisp.

PS If anyone knows how to trick WordPress into letting me display Lisp code without destroying the indenting, please let me know.

PPS Looking at the search engine traffic coming in here, I see that (besides all of the people trying to figure out carriage returns in Emacs) there are a few coming to the site for stuff like “lisp closures,” “oop in lisp” and “lisp hash tutorial.” Hopefully this post will provide a little more substance for those folks than the previous drivel I’ve spewed forth here in my clumsy efforts to get used to some of these new ideas.

PPPS Please forgive the hyperbole in the title.

——————————

Related Articles:

Closures + Lambda = The key to OOP in Lisp

Closures, Objects, Forklifts, and the quest for truth

Setting Up Emacs for Lisp Hacking in Cygwin

July 6, 2007

So there you are… hacking away merrily in Emacs with your nice tidy LispBox. But all the while a creeping awareness of the subtle differences of computing cultures take root in your consciousness. Or, more likely, they are shoved in your face every time you try to do anything in Emacs. Unlike, say, Tortoise SVN, Emacs defies conventions of the Windows operating system at every turn. It even makes you feel guilty for using a mouse. It makes you feel guilty for using any application other than Emacs!

But you’re hacking away, mastering recursion and closures… and still you wonder if you’re missing something in your Emacs experience. Would it be an even more powerful tool on its own turf? Are the people raving about the power of Emacs using it along side native Unix tools to perform mindbending feats of development magic? What would happen if you mastered that same Software Toolbox and began concatenating files with cat, reading text streams in chunks with head and tail, sorting files with sort and tsort, filtering files with tr, and removing duplicate lines with uniq? What would happen to your brain if, after opening up a man page, you actually could do something useful with what you found on the screen? Oh heck… you already pledged a lifetime of effort in your quest to understand Lisp macros… why not pledge another one for Emacs and a third for obscure Unix commands.

You install Cygwin on your box. It’s a painless process… and you even check everything Lisp related no matter how buried they are in that strange tree of files. You open Emacs just fine… and it doesn’t appear to know about any of those Lisp programs you pulled down. So you go back to your Cygwin setup and look for slime, but it doesn’t turn up.

So you manually download the slime-2.0.tgz file. You created a folder in your Cygwin directory… and you even manage to “unzip” it:

gzip -dc slime-2.0.tgz | tar -xof -

(Though you’ll never admit to having actually typed “man untar“.)

You pr README in the new slime directory and discover that Emacs need a few lines of code in order to grok Slime’s existence. No problem! You just need to add them to your .emacs file! But… it’s been months since you did that and you can’t remember how to set up a home directory… and its probably a little different in Cygwin anyway– and hey, you don’t always want Slime to do its little song and dance every single time you open up Emacs. So you open up the README file with Emacs, copy the text over to a new file and create the file slime.el:

(add-to-list ‘load-path “/cygdrive/c/cygwin/lispy/slime-2.0/”) ; (the path to where you unzipped slime-2.0.tgz)
(setq inferior-lisp-program “/cygdrive/c/cygwin/bin/clisp.exe”) ; this is where Cygwin puts the clisp program
(require ‘slime)
(slime-setup)

After saving the file, you just type M-x load-file and give Emacs the file-path to your new file to execute that elisp code… then M-x slime… and suddenly you see that comforting image that brings back such fond childhood memories of Hanukkah and going to the temple. Or something like that.

(If you happen to use Rxvt, you might be shocked by the new color scheme for your REPL screen… and be irritated by the garbage characters that hamper your M-x shell experience. And you wonder if maybe you should be using Cygwin from Emacs instead of the other way around….)

You rise from your swivel chair with a new confidence… and stride from your lair knowing that, in a pinch, you’ll be able to configure Slime with other versions of Emacs and Lisp… and you won’t have to wait for someone to make a new version of LispBox to work with Emacs 22.

A Fly in the Rxvt Ointment

July 5, 2007

I’ve been messing with Cygwin lately– so far mainly to grep source code files from multiple projects without having to load them up into irritating bloated IDE sessions to run Find GUI’s that operate with small counter-intuitive differences. It’s handy to be able to dump the output into a text-file like this:

grep -i your_pattern_here */*.* > FileName.txt

The above command searches all of files one level down from the current directory and ignores case– and dumps the results into FileName.txt. Thanks to a Blasphemous Bit from Bob McCormick, I’ve been using Rxvt lately, so I have a much better terminal than that crusty old MS-DOG cmd screen. Lots of “real estate” now. A nice small font. Lots less scrolling. Yes indeed, we now have Cygwin Nirvana.

Imagine my surprise when emacs won’t open my text file:

emacs: Cannot connect to X server :0.
Check the DISPLAY environment variable or use `-d’.
Also use the `xhost’ program to verify that it is set to permit
connections from your machine.

After googling a dozen web pages, running man a few times, and experimenting with various DISPLAY settings, I discovered that all I really needed to do was open emacs with the -nw option.

emacs -nw FileName.txt

Yes!

Emacs had gotten “broken” in Rxvt after I downloaded a bunch of new programs for Cygwin, so I don’t know for sure what it was that triggered the problem. (It is nice having all of that extra real estate to work with in that terminal mode, but I haven’t gotten around to figuring out how to run Slime and Lisp from there, yet.)

Oh, here’s a few of bonus Unix tips just for you:

If you want to see all of your environment variables, type printenv.

If you’re reading a man page and want to do more than just keep hitting the space bar… try hitting Ctrl-v and Alt-v to page up and page down. If you just want it to go away, try typing Ctrl-z. (Hmm… I wonder how many other Emacs commands work here…?)

If you are moving through directories looking for a file and you can’t tell the difference between your files and your directories because they all show up the same color or whatever… then you can use the cd command to help tell them apart. You probably already use the tab key to auto-complete your folder names while changing directories. Well… if you hit tab when a folder name is already typed out the whole way, then a directory gets printed out with all of the folders marked with a / at the end of their names. Rock on with your bad Unix self!

Ah well… don’t let any cryptic error messages ruin your morning!


Follow

Get every new post delivered to your Inbox.