Overview of Reactive GUI Programming

Traditionally, Graphical User Interface (GUI) development and Object-Oriented Programming (OOP) go hand in hand. GUI programming as we understand it today was born with the object-oriented programming language Smalltalk. Ever since, plenty of object-oriented GUI toolkits in OOP languages—and even primarily not-OOP languages like C—came into existence and ultimately into the mainstream. Not only historical or empirical arguments support the union of OOP and GUIs. Even just applying our intuition we should clearly see a natural correspondence between OOP concepts and GUI concepts. OOP seems to simply be made for GUI programming. And still, it remains challenging up to this day. From a pessimistic perspective we might assume that we already have reached the lower bound of necessary complexity for GUI programming. Recent developments particularly in the world of reactive programming suggest a different picture though. In this article I thus want to give an overview of reactive and other modern approaches to the development of GUIs in order to let you decide if the picture is worth paying for.

Challenges in GUI Programming

One might wonder what exactly it is that makes GUI programming challenging. A good overview of some typical problems in GUI programming is given in the paper Developing GUI Applications: Architectural Patterns Revisited . The author identifies four main problem categories: creating and assembling the GUI, handling user input, dialog control and integrating GUI and business logic. Although all these areas are hard, the parts of a GUI program that are concerned with interactivity are arguably the hardest to tame. Not for nothing do most modern approaches try to tackle this particular problem. On top of that, managing the (asynchronous) interactions of many external signals in a GUI will gain more and more importance in the future (“Internet of Things”).

The classical approach to handle user/signal input and interactions between GUI components is callback-based. But callbacks have a couple of severe deficits. 1

  • The control flow is “scattered”; events may occur at arbitrary times, callbacks may be added and removed on-the-fly, etc.
  • Data is exchanged via shared state and side effects.
  • Callback execution is uncoordinated; callbacks may trigger other callbacks etc. and change propagation follows a “flooding” scheme.

The quote is from C++React’s documentation. The term “callback hell” was coined to refer to the problems of callbacks. The following is a selection of links that further illustrate these problems.

Reactive Programming

Reactive programming is generally regarded as a promising alternative to callback-based programming without its shortcomings. In a recent empirical study it was even shown that program comprehension is better with reactive programs than callback-based ones. A good but also somewhat fluffy overview of reactive programming is given by the Reactive Manifesto. The video Reactive Design & Language Paradigms goes into the applicability of different paradigms for building reactive applications. One could even say that modern GUI toolkits like JavaFX are already quite “reactive” by themselves seeing as they have data-binding and observable (“time-varying”) values/properties/collections. Scratching the surface of the term “reactive programming” does not bring us far along though. Let us rather consider some more concrete branches of reactive programming that also show promise for GUI development.

Functional Reactive Programming

Functional Reactive Programming (FRP) is a branch of functional programming which was motivated by the goal to make animations, interactive programming and ultimately GUI programming better representable and more idiomatic in functional languages. The term FRP is hotly debated. Some understand it as it was originally coined in the paper Functional Reactive Animation while others take a more liberal understanding. This article takes the more liberal approach and understands FRP as a paradigm around data flows, change propagation and time-varying values or event streams using functional building blocks. As this debatable understanding suggests, there are many variations of FRP. The following are links that, among other aspects, try to provide an overview of the FRP landscape. 2

The following links provide motivation for FRP.

The following are links to a couple of interesting and practical FRP projects. 3

Not everything’s rosy in FRP. There are many criticisms and open questions with respect to FRP which are partially discussed in some of the previous links. The thread Limitations of FRP contains some interesting criticisms. 5

Event Stream Programming

As the name suggests, this paradigm is concerned with modelling interactions as streams of events. It was initially conceived in the framework Reactive Extensions (Rx) for .NET. The following links provide very good information to learn more about this paradigm.

A project I want to specially emphasize is ReactFX as its goal is the application of event stream FRP to the development of GUIs. The author Tomas Mikula’s blog contains very convincing examples of FRP’s usefulness for real GUI tasks like syntax highlighting. In short, the advantages of using ReactFX’s approach for GUI programming are less side-effects/mutable state (→ less error-proneness and hidden dependencies), better composability, more declarative/explicit code, more principled ways to prevent glitches and powerful ways to express asynchronous requirements. 6

Non-functional” Reactive Programming

Explicitly searching for reactive programming approaches that are not FRP yields not a lot of results. Nonetheless, there are interesting projects that want to combine the imperative or object-oriented paradigm with the reactive paradigm.

Other Approaches

It seems that every couple of minutes a new JavaScript fronted framework is born. Keeping track of all these frameworks and their different approaches is hard. There is one approach though, originally conceived by React.js, that quite directly goes against the current wisdom of structuring JavaScript fronted frameworks yet still seems convincing. The rough idea is that instead of trying to keep the many GUI components consistent by piece-wise mutations/updates a la MV*, the GUI is just recomputed from scratch on each interaction. The following are a couple of very interesting links about React and its novel approach.

A related idea is to centralize the state of an application instead of distributing it among different objects as is normally done with classical MV*. This idea is further characterized in the following links.

Reactive programming is one way to tame callbacks. State machines are another. The following links explain the motivation and advantages of state machines over callbacks.

Yet another approach to simplify GUI programming (or not) are immediate mode GUIs.

For Android there is Macroid and Scaloid.

Conclusion

The current remaining difficulties of GUI programming exist not due to OOP per se, as the introduction might have conveyed, but rather primarily due to callbacks or, in OOP terms, the observer pattern. The most promising idea to improve GUI programming seems to be event stream FRP like exemplified by ReactFX. Even though this article focused on GUI programming, the ideas from the presented projects could be applied elsewhere where callback-based programming is used. 7



The following are further relevant links I found after having published this article.


  1. Callbacks, listeners, observers, signal-slot mechanisms represent essentially the same concept or, put another way, share the same shortcomings. 

  2. I remember searching the internet a couple of years ago for a more idiomatic way of writing GUIs in a functional style. The answer always seemed to be that FRP is the canonical way to write GUIs in functional languages and more often than not some links to obscure papers or projects were given as proof. Of course, the obscurity of these links stood in stark contrast to these answers’ claims. In any case, I was much too inexperienced to critically assess the given information and so FRP remained this “siren call” for me that I maybe someday could hope to understand. Now that I have recently delved once again into FRP I finally understood that FRP really was rather obscure at that time and only recently more approachable FRP projects came into existence. 

  3. Admittedly, Scala.React and REScala are not so easy to set up and play with, but the information in the respective papers is very practical in terms of reactive GUI programming. And, afaik, the project from the paper “Practical Functional Reactive Programming” is not publicly accessible. 

  4. Without a doubt, Elm is the most approachable of all projects. 

  5. Most of the criticisms does not apply to event stream programming though. 

  6. Similar projects to ReactFX are ReactiveCocoa with which the Github Mac App has been built and ReactiveUI

  7. If you are interested you could checkout my thesis “Comparison of Object-Oriented and Functional Programming for GUI Development” where some approaches from this article are explored and analyzed in more detail. If you expect to get the answer “OOP is objectively better” or “FP is objectively better and here is the proof” then you are going to be disappointed. The thesis has an exploratory style and mostly presents different concepts for concrete examples. Of course, I tried to give assessments and recommendations but not an empirical or absolutely objective verdict. I think though that the thesis can serve as a first step/overview on the road to a more empirical or objective understanding of GUI development approaches. This is why I tried to extract the case studies from the thesis into a “notational usability benchmark for GUI programming” with the title 7GUIs. In a future article I will go into more detail about 7GUIs and the thesis. 

Published: 14.09.2014 Last modified: 09.05.2015
Comment? Mail or tweet me.