user-interface - programming - haskell gui example




Is functional GUI programming possible? (10)

I've recently caught the FP bug (trying to learn Haskell), and I've been really impressed with what I've seen so far (first-class functions, lazy evaluation, and all the other goodies). I'm no expert yet, but I've already begun to find it easier to reason "functionally" than imperatively for basic algorithms (and I'm having trouble going back where I have to).

The one area where current FP seems to fall flat, however, is GUI programming. The Haskell approach seems to be to just wrap imperative GUI toolkits (such as GTK+ or wxWidgets) and to use "do" blocks to simulate an imperative style. I haven't used F#, but my understanding is that it does something similar using OOP with .NET classes. Obviously, there's a good reason for this--current GUI programming is all about IO and side effects, so purely functional programming isn't possible with most current frameworks.

My question is, is it possible to have a functional approach to GUI programming? I'm having trouble imagining what this would look like in practice. Does anyone know of any frameworks, experimental or otherwise, that try this sort of thing (or even any frameworks that are designed from the ground up for a functional language)? Or is the solution to just use a hybrid approach, with OOP for the GUI parts and FP for the logic? (I'm just asking out of curiosity--I'd love to think that FP is "the future," but GUI programming seems like a pretty large hole to fill.)


My question is, is it possible to have a functional approach to GUI programming?

The key words you are looking for are "functional reactive programming" (FRP).

Conal Elliott and some others have made a bit of a cottage industry out of trying to find the right abstraction for FRP. There are several implementations of FRP concepts in Haskell.

You might consider starting with Conal's most recent "Push-Pull Functional Reactive Programming" paper, but there are several other (older) implementations, some linked from the haskell.org site. Conal has a knack for covering the entire domain, and his paper can be read without reference to what came before.

To get a feel for how this approach can be used for GUI development, you might want to look at Fudgets, which while it is getting a bit long in the tooth these days, being designed in the mid 90s, does present a solid FRP approach to GUI design.


The Haskell approach seems to be to just wrap imperative GUI toolkits (such as GTK+ or wxWidgets) and to use "do" blocks to simulate an imperative style

That's not really the "Haskell approach" -- that's just how you bind to imperative GUI toolkits most directly -- via an imperative interface. Haskell just happens to have fairly prominent bindings.

There are several moderately mature, or more experimental purely functional/declarative approaches to GUIs, mostly in Haskell, and primarily using functional reactive programming.

Some examples are:

For those of you not familiar with Haskell, Flapjax, http://www.flapjax-lang.org/ is an implementation of functional reactive programming on top of JavaScript.


All these other answers are built up upon functional programming, but make a lot of their own design decisions. One library that is built basically entirely out of functions and simple abstract data types is gloss. Here is the type for its play function from the source

-- | Play a game in a window. Like `simulate`, but you manage your own input events.
play    :: Display              -- ^ Display mode.
        -> Color                -- ^ Background color.
        -> Int                  -- ^ Number of simulation steps to take for each second of real time.
        -> world                -- ^ The initial world.
        -> (world -> Picture)   -- ^ A function to convert the world a picture.
        -> (Event -> world -> world)    
                -- ^ A function to handle input events.
        -> (Float -> world -> world)
                -- ^ A function to step the world one iteration.
                --   It is passed the period of time (in seconds) needing to be advanced.
        -> IO ()

As you can see, it works entirely by supplying pure functions with simple abstract types, that other libraries help you with.


As of 2016, there are several more, relatively mature FRP frameworks for Haskell such as Sodium and Reflex (but also Netwire).

The Manning book on Functional Reactive Programming showcases the Java version of Sodium, for working examples, and illustrates how an FRP GUI code base behaves and scales in comparison to imperative as well as Actor based approaches.

There's also a recent paper on Arrowized FRP and the prospect of incorporating side effects, IO and mutation in a law abiding, pure FRP setting: http://haskell.cs.yale.edu/wp-content/uploads/2015/10/dwc-yale-formatted-dissertation.pdf.

Also worth noting is that JavaScript frameworks such as ReactJS and Angular and many others either already are or are moving towards using an FRP or otherwise functional approach to achieving scalable and composable GUI components.


Functional programming may have moved on from when I was at university, but as I recall the main point of a functional programming system was to stop the programmer creating any “side effect”. However users buy software due to the side effects that are created, e.g. updating a UI.


I would actually say that functional programming (F#) is much better tool for user interface programming than for example C#. You just need to think about the problem a little bit differently.

I discuss this topic in my functional programming book in Chapter 16, but there is a free excerpt available, which shows (IMHO) the most interesting pattern that you can use in F#. Say you want to implement drawing of rectangles (user pushes the button, moves the mouse and releases the button). In F#, you can write something like this:

let rec drawingLoop(clr, from) = async { 
   // Wait for the first MouseMove occurrence 
   let! move = Async.AwaitObservable(form.MouseMove) 
   if (move.Button &&& MouseButtons.Left) = MouseButtons.Left then 
      // Refresh the window & continue looping 
      drawRectangle(clr, from, (move.X, move.Y)) 
      return! drawingLoop(clr, from) 
   else
      // Return the end position of rectangle 
      return (move.X, move.Y) } 

let waitingLoop() = async { 
   while true do
      // Wait until the user starts drawing next rectangle
      let! down = Async.AwaitObservable(form.MouseDown) 
      let downPos = (down.X, down.Y) 
      if (down.Button &&& MouseButtons.Left) = MouseButtons.Left then 
         // Wait for the end point of the rectangle
         let! upPos = drawingLoop(Color.IndianRed, downPos) 
         do printfn "Drawn rectangle (%A, %A)" downPos upPos }

This is a very imperative approach (in the usual pragmatic F# style), but it avoids using mutable state for storing the current state of drawing and for storing inital location. It can be made even more functional though, I wrote a library that does that as part of my Master thesis, which should be available on my blog in the next couple of days.

Functional Reactive Programming is a more functional approach, but I find it somewhat harder to use as it relies on quite advanced Haskell features (such as arrows). However, it is very elegant in a large number of cases. It's limitation is that you cannot easily encode a state machine (which is a useful mental model for reactive programs). This is very easy using the F# technique above.


One of mind-opening ideas behind Functional Reactive Programming is to have an event handling function producing BOTH reaction to events AND the next event handling function. Thus an evolving system is represented as a sequence of event handling functions.

For me, learning of Yampa became a crucial poing to get that functions-producing-functions thing properly. There are some nice papers about Yampa. I recommend The Yampa Arcade:

http://www.cs.nott.ac.uk/~nhn/Talks/HW2003-YampaArcade.pdf (slides, PDF) http://www.cs.nott.ac.uk/~nhn/Publications/hw2003.pdf (full article, PDF)

There is a wiki page on Yampa at Haskell.org

http://www.haskell.org/haskellwiki/Yampa

Original Yampa home page:

http://www.haskell.org/yampa (unfortunately is broken at the moment)


Since this question was first asked, functional reactive programming has been made a bit more mainstream by Elm.

I suggest checking it out at http://elm-lang.org , which also has some truly excellent interactive tutorials on how to make a fully functional in-browser GUI.

It allows you to make fully functional GUI's where the code you need to supply yourself consists only of pure functions. I personally found it a lot easier to get into than the various Haskell GUI frameworks.


To address this I posted some thoughts of mine in using F#,

http://fadsworld.wordpress.com/2011/04/13/f-in-the-enterprise-i/ http://fadsworld.wordpress.com/2011/04/17/fin-the-enterprise-ii-2/

I'm also planning to do a video tutorial to finish up the series and show how F# can contribute in UX programming.

I'm only talking in context of F# here.

-Fahad


Whether you're in a hybrid functional/OO language like F# or OCaml, or in a purely functional language like Haskell where side-effects are relegated to the IO monad, it's mostly the case that a ton of the work required to manage a GUI is much more like a "side effect" than like a purely functional algorithm.

That said, there has been some really solid research put into functional GUIs. There are even some (mostly) functional toolkits such as Fudgets or FranTk.





functional-programming