Functional User Interfaces

Nick @stanchme
http://github.com/stanch

(please change slides with <space>)
# Functional, huh?

Composability

pipes

Abstraction

legos
# User Interfaces
## In a nutshell * Displaying stuff * Reacting to user input

The Awkward Layouts

## What we need * Reusable * Composable * Flexible
## Android XML ![xml](xml.png) * Awkward modularity
## Javascript {{{}}}-s ![{{}}]({{}}.png) * String-based? Duh...
# The Composable Layouts
## ScalaTags [*](https://github.com/lihaoyi/scalatags) * Just Scala code * Use values and modules
## Demo [![demo](scalatags.png)](http://www.scala-js-fiddle.com/gist/e30f7c897b4ca822ca37)
## Hiccup [*](https://github.com/weavejester/hiccup) ### same idea in Clojure... ```clojure (html [:span {:class "foo"} "bar"]) ```
## Dommy [*](https://github.com/Prismatic/dommy) ### and again... ```clojure (node [:div#id.class1 (for [r (range 2)] [:span.text (str "word" r)])]) ```
## Teacup [*](https://github.com/goodeggs/teacup) ### and in CoffeeScript... ```coffeescript output = render -> ul -> li 'Bergamot' li 'Chamomile' ```

The
Flying
Spaghetti
Code
Monster

## Wikipedia on Spaghetti ![spag](spaghetti.png) ![rav](ravioli.png)
## UI is the new black ![neri](neri.jpg)
## Adobe on UI [*](http://stlab.adobe.com/wiki/images/0/0c/Possible_future.pdf) * 1/3 code is event handling * 1/2 bugs are in that code
# Dataflow programming
## Establishing connections ![moog](moog.jpg)
## Remember MS Excel? ![excel](excel.png)
## Signals * Mouse is a signal * Textbox is a slot * We need the cable!
## Elm [*](http://elm-lang.org/) * Signal-based language * Compiles to HTML+CSS+JS
## Demo [![elm](elm.png)](http://elm-lang.org/edit/examples/Reactive/Position.elm)
## A complete example [![elm](elm2.png)](http://elm-lang.org/edit/examples/Intermediate/Physics.elm)
## Event Streams * Keypress is an event * Transform it * Connect to a textbox
## bacon.js * JavaScript library * Turns DOM events into transformable streams
## Demo [![bacon](bacon.png)](http://baconjs.github.io/)
## Observables ### same idea * Reactive Extensions [*](https://rx.codeplex.com/) * RxJava [*](https://github.com/Netflix/RxJava)
# Meanwhile, in our phones
## Macroid [*](https://github.com/macroid/macroid) > Experimental modular functional UI language for Android, written in Scala.
## Bricks ```scala w[Button] ```
## Bricks ```scala l[LinearLayout]( w[Button], w[TextView] ) ```
## Bricks ```scala val brick1 = w[Button] val brick2 = w[TextView] l[LinearLayout]( brick1, brick2 ) ```
## Tweaks ```scala w[TextView] <~ text("Hello") ```
## Tweaks ```scala def largeText(str: String) = text(str) + TextSize.large + padding(left = 8 dp) myTextView <~ largeText("Hello") ```
## A complete layout ```scala var greeting = slot[TextView] l[LinearLayout]( w[Button] <~ text("Greet me!") <~ On.click { greeting <~ show }, w[TextView] <~ text("Hello there") <~ wire(greeting) <~ hide ) ```
## Snails ```scala myTextView <~~ fadeIn(400) ```
## Snails ```scala myTextView <~~ fadeIn(400) <~ text("Faded!") ```
## Snails ```scala val blink = fadeIn(400) ++ delay(2000) ++ fadeOut(400) myTextView <~~ blink ```
## UI actions ```scala val action = myTextView <~ text("Foo") <~ show ```
## UI actions ```scala val action1 = myTextView <~ text("Foo") <~ show val action2 = myProgressBar <~ hide runUi(action1 ~ action2) ```
## UI actions ```scala runUi { (myProgressBar <~~ fadeOut(400)) ~~ (myTextView <~~ blink) ~~ (myOtherTextView <~ text("’SUP?")) } ```
## Tweaks & Signals ```scala // create a reactive variable val caption = rx.Var("Olá") // set text to “Olá” myTextView <~ caption.map(text) // text automatically updates to “Adeus” caption.update("Adeus") ```
# Advanced Ideas
## Drawing a figure * Wait till mouse is down * Draw while it moves * Finish once mouse is up
## Event Stream Workflows [*](http://infoscience.epfl.ch/record/176887/files/DeprecatingObservers2012.pdf) ```scala Reactor.loop { self ⇒ // step 1 val path = new Path((self await mouseDown).position) // step 2 self.loopUntil(mouseUp) { val m = self awaitNext mouseMove path.lineTo(m.position) draw(path) } // step 3 path.close() draw(path) } ```
## Demo [![flow](flow.png)](http://www.scala-js-fiddle.com/gist/9759723/ScalaAsyncPaintbrush.scala)
## Further Reading * See [*](#)-s in the slides * [The “Deprecating Observers” paper (must read!)](http://infoscience.epfl.ch/record/176887/files/DeprecatingObservers2012.pdf) * [A comprehensive overview of Haskell GUI libraries](http://www.slideshare.net/GideonSireling/graphical-user-interfaces-in-haskell-57554808)
This presentation: http://stanch.github.io/funlx-meetup-2