Archive for the 'functional programming' Category

Layout Language

February 8, 2009

To my surprise, I didn’t get any error messages any longer after I stopped using multithreading. All I had to do to fix it was catch all exceptions from the evaluation loop and call a function to print an error message when an exception was caught, but I didn’t realize that at first. Instead, I wasted many hours fighting with Chicken. I got tired and frustrated and didn’t get as much work done as I had hoped.

However, I did start hacking on a sublanguage for automatic layout of user interface components. The idea is that you should be able to specify a layout using a clean declarative language, much like HTML or Mozilla’s XUL. That way you don’t have to write as much code to arrange buttons and the like, and the specifications will be much more readable and easier to change than imperative code.

Here is an example of the kind of declaration I’m aiming to support:

(hbox (width: 100 %)
  (hbox (align: left) ship tiger stuka)
  (hbox (align: right) end-button exit-button))

A hbox is a container that arranges its components horizontally, from left to right. In this case, there is a hbox that contains two other hboxes. One of them is left aligned and contains the components ship, tiger and stuka; And the other one is right aligned and contains end-button and exit-button. In other words, it means something like the following pseudo-HTML:


<hbox width="100%">
 <hbox align="left"> ship tiger stuka </hbox>
 <hbox align="right"> end-button exit-button </hbox>
</hbox>

Box nesting does not work yet, but alignment does. Automatic layout management actually appears to be quite easy to implement, at least if all you want is something HTML-like. You just make two passes over the tree–first, a bottom-up pass that calculates the size of all components, and then a top-down sweep that positions them.

After writing some code for arranging components horizontally I asked a friend of mine who is very proficient in functional languages if he knew a general way of expressing the iteration that could replace the ad-hoc code I had written. He came up with this neat piece of code and its brilliant name:

;; Return a list of results from applications of ‘termfun’ to the
;; elements of ’sequence’ and a carry.
;; ‘carryfn’ is used to calculate the next carry from the previous one
;; and the current element of the sequence.

(define (map/carry termfn carryfn carry sequence)
  (if (null? sequence)
    ’()
    (cons (termfn (car sequence) carry)
      (map/carry termfn carryfn
        (carryfn (car sequence) carry)
        (cdr sequence)))))

Using map/carry I could express a function for horizontal distribution of components without using any explicit iteration. Beautiful! Thanks, Tord. I considered many names for a similar iteration construct that remembered earlier results, but none of them was as succinct as “map/carry”.