UI Paradigm from Scratch August 28th, 2009
Patrick Stein

I’m not fond of MVC and yet I know of nothing better. What would I want in an alternative?

Most UI toolkits claim to follow the model-view-controller paradigm if they make any such claim at all. In my experience though, they either mush together the controller and view, or the model and view, or all three. As such, there isn’t an opportunity to have the same information represented in multiple places within the interface. Instead, you have repeated information that is synchronized through a complex scaffolding of change listeners. Yuck.

Target platform

First, I should mention why I want such a thing. I am planning to participate in a study group centered around this MIT OpenCourseWare course in Numeric Photography. I’ve done plenty of digital imaging in my day. The assignments for this course though seem to center on novel user interfaces to digital imaging and artistic value of the end results. The original course was all done as Java applets. I considered using Armed Bear Common Lisp to try to write Lisp code that interacted with the user through a Java applet. My initial tests on this went poorly since the ABCL code wants to read and write from your .abclrc and such. I toyed with code signing and permission granting on it, but wasn’t too satisfied with how easily someone else would be able to use it. Plus, I wasn’t too keen on doing so much Java.

So, I want to start with as few dependencies as possible for standalone Lisp applications. If I could keep the dependencies down to a GUI library of my own crafted atop cl-opengl and cl-png, that would be great. I suspect that I will have to throw in zpb-ttf at some point to get text into the UI, too.

Toolkit Structure

I am going to use the example of a simple checkbox. At its heart, a checkbox is simply a boolean value. The meat or logic of the code doesn’t have to care whether the checkbox is visible or enabled or being clicked or has recently changed. The meat of the code only has to know if it is checked or not. It would be nice if I could get away with just having a boolean anywhere in my code. However, some things will need to be triggered when the boolean changes. As such, I am going to need some setter/getter artifice around the boolean. So, let’s make a structure with a single boolean slot.

(defclass checkbox ()
  ((value :initarg :value :type (member nil t)))
  (:default-initargs :value nil))

Let’s call this the Checkbox Base.

This is all that most of my application will need to know. Somehow there is a checkbox. It is either checked or not.

How is the checkbox state presented in the interface? It could be drawn on the screen as a little box that either contains a check or not. It could be drawn as a menu item that either has a check beside it or not. It could be reflected in the state of some LED somewhere. It could be presented in hundreds of web browsers across the company as either a green box or a red box. Let’s call each of these a Checkbox Representation.

Somehow, each of these Checkbox Representations has to be notified when the value changes. If I am willing to also include a dependency on Cells (which hasn’t been touched since May of 2005), then I can get this kind of notification for free.

(defclass checkbox ()
  ((value :initform (c-in nil) :accessor checkbox-value)))

(defclass checkbox-as-colored-box ()
  ((checkbox :initarg :checkbox :type checkbox :reader checkbox)
   (color :cell t :initform (c? (if (checkbox-value (checkbox self))
                                    :green
                                    :red)))))

(def-c-output color ((self checkbox-as-colored-box))
  (redraw-checkbox-as-colored-box new-value))

Any time the value of the checkbox changes, the color of the checkbox-as-colored-box will change and the trigger to redraw-checkbox-as-colored-box will be invoked with the new color value.

If I don’t use Cells, then I have to create a layer around the checkbox that tracks who needs to be notified when the value changes. Let’s call this a Checkbox Monitor. It is very tempting to fold this right into the checkbox. After all, when the checkbox changes, the monitor has to know. For a slightly better division of functionality, one might make monitored-checkbox a subclass of checkbox:

(defclass monitored-checkbox (checkbox)
  ((listeners :initform nil)))

In this way, UI components can register with the monitored-checkbox, but the main application never has to notice that the checkbox has the weird methods for adding listeners and such. With an appropriate :around or :after method, the checkbox code doesn’t even have to know if it is part of a monitored-checkbox. It would be nice if the code didn’t have to know this at instantiation time, but I’m not seeing an obvious way around that without Cells.

With Cells, each representation could monitor the Checkbox Base. Without the Cells-type approach, there can really only be one Monitor per Base. (Technically, there could be more, but they could only be through a direct inheritance chain… you could wrap the Monitor with a Monitor2 and that with a Monitor3, etc. But, you wouldn’t want to try to instantiate a Monitor123 or anything like that.) For now, let’s explore the non-Cells case.

The idea so far is that you can create a Checkbox Monitor which is a subclass of Checkbox Base. Then, you can create some Checkbox Representations and register them with the monitor. The meat of your code can think of it as a Checkbox Base.

How is it toggled? There are a variety of ways that could happen. Someone could hit a global hot-key that toggles the checkbox. Someone could select a menu item that toggles the checkbox. Someone could mouse click on a representation of that checkbox. My application could receive an event from a remote source like a secondary display, a database, or a filesystem that toggles the checkbox. Someone could hit the space bar or the enter key while a representation of that checkbox has keyboard focus.

I am not sure we need to create a class hierarchy around changing the checkbox. We can simply call the setter on the checkbox. The monitor will catch it and notify everyone who needs to know. Further, the checkbox itself will be set for anyone who needs to passively query (rather than needing to track its every change).

The big question then is can we enable or disable the checkbox? This would have to either be a property of the Checkbox Base (which doesn’t seem right to me) or a joint effort spanning all places that wish to toggle the checkbox (which also doesn’t seem right). Fortunately, I think we can use multiple-inheritance and more :around methods to take care of this.

(defclass checkbox ()
  ((value :initform nil :type (member nil t) :accessor checkbox-value)))

(defclass monitor ()
  ((listeners :initform nil)))

(defclass enabler ()
  ((enabled :initform t :type (member nil t) :accessor control-enabled)))

(defclass enabled-checkbox-monitor (enabler monitor checkbox)
  ())

(defmethod (setf checkbox-value) :around (new-value checkbox)
  (when (control-enabled checkbox)
    (call-next-method)))

Is this any better than the status quo? I’m not sure. I will have to write more code to find out.

Casting to Integers Considered Harmful August 6th, 2009
Patrick Stein

Background

Many years back, I wrote some ambient music generation code. The basic structure of the code is this: Take one queen and twenty or so drones in a thirty-two dimensional space. Give them each random positions and velocities. Limit the velocity and acceleration of the queen more than you limit the same for the drones. Now, select some point at random for the queen to target. Have the queen accelerate toward that target. Have the drones accelerate toward the queen. Use the average distance from the drones to the queens in the i-th dimension as the volume of the i-th note where the notes are logarithmically spaced across one octave. Clip negative volumes to zero. Every so often, or when the queen gets close to the target, give the queen a new target.

It makes for some interesting ambient noise that sounds a bit like movie space noises where the lumbering enemy battleship is looming in orbit as its center portion spins to create artificial gravity within.

I started working on an iPhone application based on this code. The original code was in C++. The conversion to Objective C was fairly straightforward and fairly painless (as I used the opportunity to try to correct my own faults by breaking things out into separate functions more often).

Visualization troubles

uniform
The original code though chose random positions and velocities from uniform distributions. The iPhone app is going to involve visualization as well as auralization. The picture at the right here is a plot of five thousand points with each coordinate selected from a uniform distribution with range [-20,+20]. Because each axis value is chosen independently, it looks very unnatural.

gauss
What to do? The obvious answer is to use Gaussian random variables instead of uniform ones. The picture at the right here is five thousand points with each coordinate selected from a Gaussian distribution with a standard-deviation of 10. As you can see, this is much more natural looking.

How did I generate the Gaussians?

I have usually used the Box-Muller method of generating two Gaussian-distributed random variables given two uniformly-distributed random variables:

(defun random-gaussian ()
  (let ((u1 (random 1.0))
        (u2 (random 1.0)))
    (let ((mag (sqrt (* -2.0 (log u1))))
          (ang (* 2.0 pi u2)))
      (values (* mag (cos ang))
              (* mag (sin ang))))))

But, I found an article online that shows a more numerically stable version:

(defun random-gaussian ()
  (flet ((pick-in-circle ()
           (loop as u1 = (random 1.0)
                as u2 = (random 1.0)
                as mag-squared = (+ (* u1 u1) (* u2 u2))
                when (< mag-squared 1.0)
                return (values u1 u2 mag-squared))))
    (multiple-value-bind (u1 u2 mag-squared) (pick-in-circle)
      (let ((ww (sqrt (/ (* -2.0 (log mag-squared)) mag-squared))))
        (values (* u1 ww)
                (* u2 ww))))))

For a quick sanity check, I thought, let’s just make sure it looks like a Gaussian. Here, I showed the code in Lisp, but the original code was in Objective-C. I figured, If I just change the function declaration, I can plop this into a short C program, run a few thousand trials into some histogram buckets, and see what I get.

The trouble with zero

So, here comes the problem with zero. I had the following main loop:

#define BUCKET_COUNT 33
#define STDDEV       8.0
#define ITERATIONS   100000

  for ( ii=0; ii < ITERATIONS; ++ii ) {
    int bb = val_to_bucket( STDDEV * gaussian() );
    if ( 0 <= bb && bb < BUCKET_COUNT ) {
      ++buckets[ bb ];
    }
  }

I now present you with three different implementations of the val_to_bucket() function.

int val_to_bucket( double _val ) {
  return (int)_val + ( BUCKET_COUNT / 2 );
}

int val_to_bucket( double _val ) {
  return (int)( _val + (int)( BUCKET_COUNT / 2 ) );
}

int val_to_bucket( double _val ) {
  return (int)( _val + (int)( BUCKET_COUNT / 2 ) + 1 ) - 1;
}

As you can probably guess, after years or reading trick questions, only the last one actually works as far as my main loop is concerned. Why? Every number between -1 and +1 becomes zero when you cast the double to an integer. That’s twice as big a range as any other integer gets. So, for the first implementation, the middle bucket has about twice as many things in it as it should. For the second implementation, the first bucket has more things in it than it should. For the final implementation, the non-existent bucket before the first one is the overloaded bucket. In the end, I used this implementation instead so that I wouldn’t even bias non-existent buckets:

int val_to_bucket( double _val ) {
  return (int)lround(_val) + ( BUCKET_COUNT / 2 );
}

Numbers 30:2, for programmers July 20th, 2009
Patrick Stein

The role-playing game Paranoia was set in a dystopian future where a paranoid computer had seized control to protect us from Commie, mutant traitors. In the game, secret societies were strictly forbidden. As such, every character was a member of some secret society or other. One of those secret societies was the FCCCP: First Church of Christ, Computer Programmer. This, of course, tickled me. Heck, it still does.

Outside the world of role-playing games, there is a long tradition of analyzing sacred texts, pulling out every possible thread of meaning and applying those meanings to every aspect of life. I’ve been pondering a series of articles that combines the exegesis with the computer programming.

Well, this week’s sermon at our synagogue was about the verse Numbers 30:2:

If a man makes a vow to the LORD, or swears an oath to bind himself by some agreement, he shall not break his word; he shall do according to all that proceeds out of his mouth.

How could I sit there without pondering Programming by Contract? In fact, I would say that this verse goes much beyond just the contract. Every line of code makes promises. Are they promises the code can keep?

To ground the discussion, I dug around for a short function that I wrote more than a year ago. The following snippet of code takes two arrays: counter and maximum. The array elements of each are assumed to be integers. The arrays are assumed to be the same length. The value of the i-th entry in counter is assumed to be less than the i-th entry in maximum. If you think of an axis-aligned, n-dimensional cube with one corner at the origin and its opposite corner at the maximum, the goal is for counter to scan through every set of integer coordinates in the cube (well, including the faces that touch the origin, but not including the faces that touch the maximum). If every entry in maximum is b, then the result should be just like incrementing a base b number that is displayed least-significant digit first. If maximum were \left( 60, 60, 24, 7, 4 \right), the counter would count out the seconds in February (non-leap year).

(defun increment-counter (counter maximum)
  (unless (null counter)
    (let ((nn (length counter)))
      (let ((result (make-array nn :initial-contents counter)))
        (dotimes (ii nn nil)
          (when (< (incf (aref result ii)) (aref maximum ii))
            (return result))
          (setf (aref result ii) 0))))))

What promises does the above code make? The function name increment-counter is a pretty obvious promise. The function is going to increment some sort of counter. Given just the function name, what would we expect? I would expect that it takes a single argument, that argument is a reference to an integer, and that integer is incremented in place. I would be way off. Our promise is already on sketchy grounds. I’m not coming up with a particularly good name at the moment though: step-cube-walker? increment-n-dimensional-counter?

The function doesn’t increment the counter in place. Instead, it returns a newly allocated counter (or nil, if we’ve reached the end). The function declaration doesn’t make any promise that maximum will be left untouched, though Lisp doesn’t make it easy to declare that. Lisp usually handles that sort of thing by convention. The function declaration also makes no claim that the counter and maximum arguments should be arrays, let alone that they should be the same length. (Technically, the code only requires that maximum be an array. Counter can be any sequence. Further, maximum is allowed to be longer than counter, but cannot be shorter.)

Line 2 of the code doesn’t trust you to stop calling it when you’re already done. This is an interesting hedge, but not really an oath. It may rise to that level at some point though if enough code starts to depend on this utterance.

Lines 3 & 4 are the only uses of (a non-nil) counter. They work just fine for any sequence. As such, while this function always returns either nil or an array, it will accept any sequence as the counter.

Line 5 outright promises that the function is going to return nil. This is, of course, countermanded on line 7. I suppose this is akin to verses 3, 4, & 5:

[3] Or if a woman makes a vow to the LORD, and binds herself by some agreement while in her father’s house in her youth, [4] and her father hears her vow and the agreement by which she has bound herself, and her father holds his peace, then all her vows shall stand, and every agreement with which she has bound herself shall stand. [5] But if her father overrules her on the day that he hears, then none of her vows nor her agreements by which she has bound herself shall stand; and the LORD will release her, because her father overruled her.

Even though the loop on line five is released of its promise, it still feels like a cheap back door.

So, you can see that even in these eight lines of code, I have made many, many inadvertent promises. Hopefully, in future code, I will keep a more careful tongue.

TC Lispers, July Presentations Online July 19th, 2009
Patrick Stein

The July meeting of the Twin Cities Lisp Users Group was this past Tuesday. There were four presentations on the agenda:

The presentation slides and videos of the talks are available through the links above, and directly at the tclispers.org site. Enjoy!

Lisp Jump Tables July 12th, 2009
Patrick Stein

A few weeks back, I posted about how I know that I have more to grok about Lisp macros. In that post, I needed to explain Lisp macros a bit for those not in the know. The example that I used was creating a jump table.

Geoff Wozniak just posted an article in his blog wherein he explores using a macro to do jump tables using an array of functions. He performed timing tests using Tim Bradshaw’s ncase macro versus case and switch.

The timing differences there are quite amazing. I’ve toyed around with optimizations quite a bit and have never seen Allegro outperform SBCL before this. It is also interesting that CLISP may already do this jump table optimization. I have never seen CLISP come anywhere close to SBCL or Allegro before this.

Update: Including timing numbers from my own machine

My machine is a 2.4GHz Intel-based Mac with 4GB of RAM. Here are the numbers that I get for this test. (All numbers in milliseconds).

  n case ncase switch
SBCL 1.0.29 10 166 149 207
  100 185 146 191
  1000 572 147 207
CLISP 2.47 10 115 211 188
  100 117 205 219
  1000 111 206 189
ACL 8.1 (heap-limited) 10 10 20 90
  100 20 10 90
  1000 1420 20 130
CMUCL 19f 10 120 120 180
  100 150 120 210
  1000 520 120 210
Clozure v1.3-r11936 10 19 15 128
  100 108 14 130
  1000 1214 14 117

  • With Allegro (ACL), I couldn’t compile easily. I had to load it, then compile it, then load the compiled version. If I just started Allegro and tried to compile, it complained that WITH-GENSYMS was an undefined function.
  • With a heap-limited LispWorks, I failed to even compile the program. *shrug*

Updates In Email

Email:

l