opening it up with Common Lisp

Favorite weblogs

Lisp Related

Bill Clementson

Finding Lisp


Planet Lisp



Talking Points Memo

This Modern World

Working for Change

Other home


Recent Readings

Book review: Darwinia
Reviewed: Friday, August 11, 2006

Summer reading: Spin
Reviewed: Saturday, August 5, 2006

Reviewed: Tuesday, July 18, 2006

the Omnivoire's Delimma
Reviewed: Wednesday, July 12, 2006

the Golem's Eye
Reviewed: Wednesday, May 31, 2006


Graphing your relations with Address Book, OpenMCL and CL-Graph
Friday, May 12, 2006

Apple's Address book provides a convenient system wide repository for contact information. Recent versions include the ability to connect contacts together by relations. For example:

  • the Father of Gary King is Stephen King (true but not the novelist)
  • the Assistant of Jane Smith is John Doe
  • the Spouse of Wendy Delaney is Gary King

One thing that Address book doesn't provide is a way of viewing these relationships. Today's task: build an application that reads the Address book database and produces a graph showing the relations.

My first thought was to do this entirely in Apple's Object Oriented Cocoa framework. It is, after all, the easiest and most supported way to work with Apple's code. A few things, however, stood in my way: Cocoa is a big framework and I'm still learning it; I'm not aware of any Cocoa graph manipulation library that is comparable to CL-Graph; and I'm not aware of any Cocoa graph layout mechanisms comparable to GraphViz. So my second thought was to dig up some old e-mails (and here) between Richard Cook and Gary Byers on the OpenMCL mailing list and use OpenMCL and its ObjectiveC Bridge. I also looked at Richard's code for his Address Book / Google Maps mashup (look towards the bottom of the page).

Step 1 : create the interface database that lets OpenMCL talk to the Address book framework.

Step 2: use the Address book interface and Lisp to build the graph and make a DOT file of it that GraphViz will like

Step 3: use GraphViz to make an image. Voila!

Now to go over the steps in a bit more detail.

Creating an Interface Database

The OpenMCL documentation (with special thanks to Dan Knapp) is very helpful and thorough. First one use FFIGEN to read the ObjectiveC framework and create FFI files and then one use the parse-standard-ffi-files in Lisp to create the CDB databases that OpenMCL likes. As long as you don't create the FFI files in one of your OpenMCL Lisp repositories and then try to create the CDBs in a different repository -- yes, I did that and it took me a long time to figure out why things weren't working! The error message was cryptic but it was a head banger once I figured it out. I did find that I needed to go through the AddressBook headers file by hand and do each one individually (but that may be due to user error on my part). My populate script is available if you're interested in seeing it.

Using the Address book from OpenMCL

Once again, most of the work had been done for me. I used the webkit example as a template along with advice from old e-mails on the OpenMCL mailing list. The final result is available. Once this file is in place (in the OpenMCL examples folder), all you need to do is (require 'addressbook).

The great thing about the ObjectiveC bridge in OpenMCL is that one can use Cocoa classes almost as easily as you can in ObjectiveC and XCode itself. Even better, you can develop interactively without that nasty edit/compile/run cycle. (Compilers have gotten faster but it's still an appreciable delay). Rather than go over the details here, I'll let the code do the talking.

Use GraphViz to layout the graph

and here it is:

(You'll probably want to see it in its own window because of the scaling). Here is that DOT file that created this. Even this little sample shows a bunch of problems

  • The relations don't have to be in the Address Book -- which, I suppose, is a good thing -- so it's easy to have inconsistencies
  • Similarly, adding a relation from A to B doesn't create the back relation from B to A
  • Finally, the fact that it's not all that easy to add relations in the Address book means that not many get added (at least, that's true in my case).

By the way, if anyone knows how to tell GraphViz not to draw the edges and labels on top of one another, I'd appreciate it if they would tell me!

(Note that I found and fixed a minor display bug in CL-Graph while working on this example. If you want the edge labels to appear, you'll need to update).


Home | About | Quotes | Recent | Archives

Copyright -- Gary Warren King, 2004 - 2006