Declarative UI Behavior with Fruit
22 Oct 2011
Fruit is a framework for building UI workflows declaratively using continuations and functional reactive programming.
To run the demo, first build the Scala compiler plugin:
> sbt/sbt "fruit-plugin/publish-local"
Then run the demo:
> sbt/sbt "fruit-demos/run-main fruit.FruitDemo"
Defining behavior in the conventional way via observers leads to some pretty ugly code. After reading Deprecating the Observer Pattern, a paper by Martin Odersky, Tiark Rompf, and Ingo Maier, I decided to put together a little framework for writing UI behavior in a declarative style, using delimited continuations and functional reactive programming take the mess of wiring up
ActionListeners and sweep it under the rug. The outcome of this effort is Fruit, the Functional Reactive UI Thing.
Consider the following UI:
This panel includes a combo box and a label. Changes to the combo box selection are reflected in the label:
Conventionally this would require adding to the combo box an
ActionListener which would encapsulate the (relatively simple) logic of what to do with updates to the combo box selection; in this case, updating the text of the label. With Fruit, it is as simple as a one-line declaration:
This treats the combo box as a signal, and the text of the label is set to the time-varying value of the combo box signal. This can be used to build up more complex UI workflows:
label1.setText(signal(combo1)) label2.setText(signal(combo2)) label3.setText(signal(combo1) + " is " + signal(combo2)) label4.setText(signal(combo1) + " ain't " + signal(combo2))
Here we have four labels which are updated based on the selection of the first combo box, the selection of the second combo box, or both. It keeps the UI workflow together, and is much easier to reason about than with observer implementations scattered about.