(Functional) Reactive Web Development

Steven Byrnes

November 19, 2014

Abstract

We will look at a few language and library options for doing (functional) reactive web development, including Elm, RxJS, and BaconJS. F# may make a brief guest appearance in the stack as well.

Prologue

What is (F)RP?

Reactive Programming

Definition

Functional reactive programming (FRP) is a programming paradigm for reactive programming using the building blocks of functional programming. FRP has been used for programming graphical user interfaces (GUIs), robotics, and music, aiming to simplify these problems by explicitly modeling time.

Wikipedia

What?

Continuous vs discrete

Push vs pull

Different constraints

Why?

  • Declarative rather than imperative
  • Easier to reason about
  • Composability

Act 1 - “Old Sk00l”

A Simple Model

Just HTML

jQuery

$("button#specialness")
  .html("Don't click here!")
  .on( "click", somethingMagickal );

For example:

    $("#save-schnippet").on("click", function(event) {
        event.preventDefault();
        alert('you entered: ' + $("#new-schnippet").val());
    });
$  diff -u act1-html/schnippets.html act1-jquery/schnippets.html
     <link rel="stylesheet" href="../schnippets.css">
+    <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
+    <script type="text/javascript" src='https://cdn.firebase.com/js/client/1.1.1/firebase.js'></script>
+    <script type="text/javascript" src="application.js"></script>
   </head>

Act 2 - Reactive

RxJS

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function searchWikipedia (term) {
   return $.ajax({
     url: 'http://en.wikipedia.org/w/api.php',
     dataType: 'jsonp',
     data: {
       action: 'opensearch',
       format: 'json',
       search: global.encodeURI(term)
     }
   }).promise();
}

var keyup = Rx.Observable.fromEvent($('#textInput'), 'keyup')
      .map((e) => e.target.value)        // Project the text from input
      .filter((text) => text.length > 2) // Text is longer than 2 chars
      .throttle(750)                     // Pause for 750ms
      .distinctUntilChanged();           // Only if the value changed

var searcher = keyup.flatMapLatest(searchWikipedia);

var subscription = searcher.subscribe( (data) => console.log(data) );

Bacon.JS

BaconJS?

Double bacon
Double bacon

Bacon.JS

No… neither of those…

http://baconjs.github.io/
http://baconjs.github.io/

Differences

RxJS:

var keyup = Rx.Observable.fromEvent($('#textInput'), 'keyup')

BaconJS:

var keyup = $('#textInput').asEventStream('keyup')

BaconJS - Demo

Act 3 - First Class FRP

Elm

  • First order FRP
  • Haskell-like syntax (but not Haskell)
  • Code hot swapping! In the browser!
  • Time traveling debugger!

Hello World

main : Element

main = asText "Hello world"

Getting started

  • elm_dependencies.json
  • elm-get install
  • elm –make –only-js Schnippets.elm
  • elm-reactor

Demo - Schnippets

    $ cd act3-elm && elm-reactor
    Elm Reactor 0.1, backed by version 0.13 of the compiler.
    Listening on http://localhost:8000/

Epilogue

Functional? Reactive?

Fin

Other AltJS

If you like Haskell-like syntax for web development, there are several other functional AltJs languages out there: Roy, Haste, Fay, Elm, GHCJS, PureScript.

Further Reading

Presentations and intros: - Controlling Time and Space: Understanding the Many Formulations of FRP - The introduction to Reactive Programming you’ve been missing - Functional Programming in Javascript - Netflix JavaScript Talks - Async JavaScript with Reactive Extensions - What Every Hipster Should Know About Functional Reactive Programming - Reactive Manifesto

RxJS: - Home - Examples - Firebase binding - Time Flies like an Arrow

BaconJS: - Home - Making a snake game in BaconJS

Elm: - Home - Todo - Elmtris - Pong - On how to structure an Elm application - Elm: Concurrent FRP for Functional GUIs

Other interesting projects: - Radioactive

Thank You

erewhon @ { flatland | github | .tx }