The State of the Art in User Interfaces

This is a dialog that popped up just now from iTunes:

iTunes CD Lookup Results dialog

It has several noteworthy interactive features:

  1. It is not resizable.
  2. The two choices are visually identical.
  3. Copy-and-paste is disabled for the text of interest.

It also possesses a few less visible but no less interesting attributes:

  1. There is no undo once I click OK.
  2. iTunes remembers my choice1 for future insertions of the same CD.

I shall choose at random.

Moral: Current environments for interacting with computers are, putting it mildly, irretrievably broken. Our only hope lies in disruptive innovation.


  1. Fortunately, there is a method for causing iTunes to forget my choice and ask me the same question again: it is the selection Get Track Names in the Advanced menu. 

Rube Goldberg contraptions with RabbitMQ

I've just finished building and deploying this website. It uses jekyll to render the content, and the content author uses git to push the changes up to the hosting machine. From there, a nice little chain of programs arranges for the site to be rebuilt on the server and made live:

  • A git post-receive hook uses curl to HTTP POST an empty message into a RabbitMQ exchange via the RabbitHub plugin.

  • D. J. Bernstein's daemontools supervises an instance of amqp-consume, which connects to a queue bound to the exchange the post-receive hook delivers into, and whenever a message is received, invokes a shell-script. The command-line for invoking amqp-consume is roughly

    amqp-consume \
       -s localhost \
       --username=... --password=... \
       -e exchangename \
       -A \
       /path/to/rebuild-website-script
  • The shell-script invoked for every message from RabbitMQ checks out a fresh copy of the website, compiles it, and deploys the resulting static HTML into the correct location on the file system for Apache to pick up.

  • I'm also monitoring the RabbitMQ exchange using the rabbitmq-xmpp plugin talking to my desktop XMPP client, Adium, so whenever anyone does a git push, I get a message appearing in my IM client from exchangename@my.rabbitmq.hostname letting me know a new version of the site has just gone live.

I've been cited! (In a way ...)

Hee hee! This paper, on Scheme Program Documentation Tools, references docscm :-)

The scheme-reports-wg1 Google Group is hard to read

(Update: Shortly after I posted this, I contacted the working-group chair, and he quickly replied to let me know that the group's settings have been changed. It's now possible to subscribe to group activity as a spectator. Posting is still restricted to group members, of course, but now others can follow along, which makes me happy.)

It's almost impossible to follow the scheme-reports-wg1 Google Group, because

  • you can't join the google-group unless you're part of the working group itself (no joining as a spectator)
  • the interfaces available to non-google-group members are insufficient:
    • the RSS/Atom feeds truncate posts, meaning you have to click through to the google-group webpage for reading threads
    • the thread-reading pages themselves are not easy to catch up on (compare Thunderbird, an NNTP client, or even Google Reader here)
  • the volume of the list is very high at the moment.

I'd be happy if there were

  • a full-content RSS/Atom feed somewhere (for some reason I don't trust that the existing feed (or perhaps Google Reader) is doing well in keeping posts in chronological order, either); or,
  • an NNTP feed of the group (!); or,
  • a regular mailman-style mailing list for the group.

The current setup really doesn't work well for me at all, which is disappointing, as lots of the discussions I've overcome the awkwardness of the interface to read are really very interesting.

Notes on "Xoc, an Extension-Oriented Compiler for Systems Programming"

I've just finished reading "Xoc, an Extension-Oriented Compiler for Systems Programming", by Russ Cox, Tom Bergany, Austin T. Clements, Frans Kaashoek, and Eddie Kohlery. It's a description of an interesting approach to extensible compilation, for C in this case, that refines a lot of ideas that have been explored previously, bringing them together in a more compositional style than previous extensible compilers have managed to achieve.

One of the key themes in the paper is how to control extension visibility. They describe a couple of approaches they take: one, a type system used to ensure that extensions to abstract syntax are only visible to other extensions when those extensions explicitly declare knowledge of them; and two, an approach from Warth et al.'s "Statically scoped object adaptation with expanders" paper for controlling visibility of extensions to core data structures. I wonder if the latter is used to underpin the former at all.

Regarding the type system approach they take, it's interesting how it lets the extension writer provide analyses directly in terms of extension abstract syntax, rather than forcing translation to a core language before performing any analysis. We did the latter in Highwire, and the error messages referred to core-language constructs which didn't map well to source-language syntax: the user was forced to unexpand the macro in their heads to make sense of the output of the compiler. The paper refers to this problem in section 5.2, where the authors write "Since macros cannot access compiler internals, they typically do not even type check their arguments, producing cryptic errors when invoked incorrectly."

Their compiler, xoc, is a source-to-source translator at the moment, which means it's not integrated with code generation and backend optimisations and rewrites. It'd be fascinating to build a complete compiler in this style. It'd also be neat to relate this approach to extensible semantics. At the moment the extensions look quite ad-hoc. How could this framework be used, for example, to extend Scheme or ML, where there's a real semantics underneath it?

One nice feature of xoc is that it tries to preserve hygiene during rewriting. I'm curious as to whether it preserves hygiene to the degree that, say, syntax-case does; their description of the feature was a bit terse for me to be able to tell. In particular I'm interested in how it treats keywords, and where "fresh names" come in to the picture; the paper speaks simply of the code emitter renaming variables "when two distinct variables share a name".

They use a GLR parser for converting concrete syntax to abstract syntax. One of the benefits of this is its ability to deal with ambiguity, which they exploit in a couple of ways, most ingeniously in their approach to type inference (if you like) for syntax pattern variables. I'd like to learn more about how xoc computes the type of a syntax pattern variable; I wonder if a similar system could be ginned up for use with OMeta?

The laziness of most of xoc's attribute computations is rather nifty. Code generated relatively late in a compilation, when earlier passes are complete for the rest of the code, can have necessary information filled in lazily on demand, running just those parts of the previous analyses that are required.

I'd like to see some of the pattern-matching and reconstruction features of xoc employed in the context of general purpose computing. It seems to me that using a GLR parser the way they do could effectively provide concrete domain-specific syntax for algebraic data types, not just abstract syntax trees. (The question arises: when is an AST an ADT? Always?) Being able to cons up syntax for new types as easily as Haskell and ML cons up the types themselves seems like a win it's worth experimenting with. OMeta goes a step in this direction; I hope to explore it myself sometime soon.

"Git from the bottom up", by John Wiegley

This article is an excellent, excellent introduction to Git. It covers the low-level basics, which are much simpler and more elegant than you might be expecting1, and then reaches up to the less elegant but very powerful world of the Git user interface. Highly recommended.


  1. though of course, you might expect me to say that, given my own background

Messaging without time: modeless user-interfaces for programs

Most thinking about messaging seems to be framed in terms of process languages, like the π-calculus. In the π-calculus, processes evolve according to an internal clock, the ticks of which correspond to communication events between subprocesses. Many real programming languages based around messaging, like Erlang, are based around similar models, meaning that programmers write programs whose notion of time is implicit, rather than explicit. This can make it difficult to write programs which can reason about differing orders of events or cope with contradictory assertions about the state of the outside world.

An alternative way of dealing with messaging is to take an epistemic reasoning approach closely connected with Functional Reactive Programming (FRP): instead of writing programs that wait for the arrival of specific messages, one at a time, write programs that deal with a queryable monotonically increasing collection of all messages that have arrived or departed so far. Metadata about each message—the sender, the recipient, the time of receipt—are reified as queryable fields attached to each datum in the collection. The state of the program's world is directly derivable from the program itself and the collection of messages that have been exchanged thus far.

By letting programs step back from the low-level detail of the exchange of messages and take a broader overview of the whole conversation thus far, we let programs behave much more flexibly in the face of such common distributed-systems challenges as lost messages, duplicated messages, out-of-order messages, inconsistent data, and timeouts.

I've been off-and-on thinking about these timeless 'epistemic messaging' systems for a couple of years now, since a customer project let us investigate their potential suitability for a particular style of long-lived database; while I could write more, and hope to in future, I want to record an observation that occurred to me a couple of days ago about a connection between modeless user interfaces and timeless messaging systems.

In the same way that modal user interfaces constrain the interaction between the user and program into a sequential, question-and-answer style, π-calculus-style programs constrain the interaction between programs in a distributed system into a similar one-thing-at-a-time sequential style, which can lead to programs having a sensitive dependence on message arrival order. Modeless user interfaces, by contrast, make possible a more open-ended, non-linear style of interaction with the user, and epistemic messaging does the same thing for program-to-program interaction: because the state of each program (and thereby its next action) is derived from the collection of messages that have been exchanged, the program can more easily be written to cope with messages arriving in an unusual order. Epistemic-messaging programs can even be written to be able to re-plan (and maybe even re-execute) their actions if received messages were to be permitted to be replaced mid-run.

(Aside: I wonder if there's a connection here to the Curry-Howard isomorphism? A program operating epistemically over a collection of messages feels like a kind of type/formula, where a similar program in a π-calculus-like system feels like a program/proof.)

Source Code Repositories

We make a few programs that we've developed available on this server. You can download them from our source-code repositories:

Mercurial

We're gradually switching away from darcs to mercurial or git. You can browse the mercurial-controlled code with hgwebdir at 80/20.

Git

While we generally prefer to use mercurial, git is more appropriate for some projects.

  • tonyg's projects:

    • gyre: The web-log engine behind this site; written in python, very simple, blosxom-like

    • newmoon: An incredibly naive CPS-based Scheme compiler, currently torn between JVM, .NET and C backend support

Darcs

Most of our older projects are currently held in these archives, though as we switch to Mercurial and Git, this will change. You can browse the darcs-controlled code with DarcsWeb at 80/20.

GNU/Arch (tla)

These repositories are obsolete, as we've mostly switched to using darcs.

  • 2004 archives: tla register-archive http://www.eighty-twenty.org/archives/2004/
  • 2005 archives: tla register-archive http://www.eighty-twenty.org/archives/2005/

FIB in PowerPC assembly and in JONESFORTH

Recently I've been teaching myself PowerPC assembly through porting JONESFORTH to PowerPC on Mac OS X. It struck me to run the same little fibonacci-sequence microbenchmark that I ran lo these many years past. The results were interesting:

Language Implementation Detail Time (per (fib 29) call, in milliseconds) Ops/s Ratio (opt. C) Ratio (unopt. C)
PPC assembly - 24 935983000 0.43 0.205
FORTH JONESFORTH ported to PPC 277 81096000 4.95 2.37

The hand-coded assembly beats all the other entrants (perhaps unsurprisingly). The naive indirect-threaded FORTH is the fastest interpreted language, merely 5 times slower than fully optimised C.

Here's the JONESFORTH code:

: FIB DUP 2 >= IF 1- DUP RECURSE SWAP 1- RECURSE + ELSE DROP 1 THEN ;

and here's the PPC assembly (arg and result in r3):

_SFIB:  cmpwi   r3,2
        bge     1f
        li      r3,1
        blr
1:      mflr    r0
        stw     r0,-4(r1)
        addi    r3,r3,-1
        stwu    r3,-8(r1)
        bl      _SFIB
        lwz     r4,0(r1)
        stw     r3,0(r1)
        addi    r3,r4,-1
        bl      _SFIB
        lwz     r4,0(r1)
        add     r3,r3,r4
        lwz     r0,4(r1)
        addi    r1,r1,8
        mtlr    r0
        blr

Reflection on floats

Gordon Weakliem writes about literal hash-table syntax, and touches on some of the problems that programmers run in to with floating-point numbers. He writes:

12 years ago, I spent half a day in the debugger trying to figure out why the computer would not believe that 0.0 == 0.0 [...]

This triggered two thoughts:

  • floating-point numbers in GUIs should be represented differently depending on whether they are an exact representation or an inexact one - which might have saved Gordon's 12 hours. For instance, inexact representations could be a slightly different shade from exact representations, making the hidden difference between the two zeros apparent at a glance; and
  • programming languages must provide reflective access to the representation of floating point numbers, if they are used. As a programmer, I must be able to access the exact bit sequence used to represent the sign, mantissa and exponent of the float.

Regarding reflective access to floats, Java provides floatToIntBits and intBitsToFloat, and C provides (quasi-portable) pointer-based memory-aliasing type-punning to the same effect: float f = 1.23; int i = *((int *) &f);.