Gainesville-Green.com – A UCW / Common Lisp website about our environment

Introducing Gainesville-Green.com

As a piece of speculative work, we created a tool for visualizing utility usage for our fair city Gainesville, FL. We chose to write it in Common Lisp using a somewhat modified version of the UCW web framework. This will be the third site we have written in Common Lisp and the first that is publicly available. It is also our first publicly deployed site with a PostgreSql backend. We chose to use pgsql because the bridge between sqlserver on windows and Steel Bank Common Lisp on Debian/GNU/Linux is a bit leaky through the multiple layers of C. Most of the data for this site is static, and shouldn’t need to tax the database too much (not that postgres couldn’t handle it, just that we might not have all of the config worked out yet).

We are hoping that this site will be useful for local developers, the city council, and for GRU (the local utility company) in better planning and executing “green” initiatives. We also hope that by putting something in place to allow consumers to see how well they are doing ecologically (compared to those around them), that those consumers can take charge of their utility usage and make better decisions that leave the earth a better place.

We chose to write the application in Common Lisp because:

  • It allows us to get our ideas to the web with less work.
  • I don’t have to interact with xml in terms of angle brackets. In our XHTML generation library (built on CXML and CHTML) I can write functions that take, manipulate and return DOM nodes. This allows tremendous abstraction possibilities on the HTML front.
  • Macros – sometimes they are the only abstraction that works, and then they are great to work with.
  • I compile once and then never think about it again as I continuously work in a running image. I continue to compile frequently, but each of these is only for a form or file and takes very little time to finish. This has led to problems with broken check-ins, but I think that is more of an issue with my usage patterns than the environment.
  • I get to retain small pieces of my sanity that C# would mercilessly torment to Death death = new Death (my_sanity).

We will hopefully be blogging about this a bit more in the future so stay tuned if you care and if you don’t… um… continue not caring.

Metabang-Bind Accessors Patches

Note: I wrote this a while ago and never proof read / published it, so this patch was actually included in Bind a while ago.

I finally got around to trying out Gary King’s Metabang-Bind library. There has been a bit of grumbling around the office about how I might be doing it wrong, if I need to bind so many variables that I need this library. I felt this at first as well, but to some extent, the things I was working on pretty were imperative. I am writing a replacement for our invoicing program and had about twenty bindings in a row. I found the code to be neater and easier to read after switching to bind so I feel that this was a win overall.

After using it a bit, I found a few things that I wanted to add. It was pleasing to discover that the code was very easy to extend. To add a new binding pattern was simply a matter of specializing a new method based on the first token in the binding form.

The first change I made was that, when binding accessors I wanted to be able to write to the variable and have that effect the values in the object. The current binding scheme for accessors converted to a let* form. My change simply made the accessors bind using a with-accessors form instead of the let*. The older form involving the let* is still available using the :accessors-read-only symbol instead of :accessors. The following is the lift unit test demonstrating this patch in action:

1: (addtest (test-classes)
2: basic-accessors-1
3: (ensure-same
4: (bind ((obj (make-instance 'metabang-bind-class-2
5: :a 1 :b 2 :c 3 :d 4 :e 5
)
)

6: ((:accessors a c e) obj)
)

7: (setf a :a c :c)
8: (list (e obj) (c obj) (a obj))
)

9: '(5 :c :a) :test 'equal
)
)