Functional Reactive Programming



Functional Reactive Programming

0 0


bacon-oredev


On Github raimohanska / bacon-oredev

Functional Reactive Programming

Juha Paananen @raimohanska

Imperative code

List managers = new ArrayList()
for (Employee employee : employees) {
  if (employee.title.equals("manager")) {
    managers.add(e);
  }
}
return managers;
          

variables, loops, ifs, mutable data structures

FP


          employees.filter {e => e.title == "manager"}

          

FRP

a paradigm

FP - Static

FRP - Dynamic

Events and Callbacks

var active = true;
var timeout = null;
function setInactive() {
  bubble("asleep?")
  active = false;
}
function setActive() {
  if (!active) {
    bubble("back!")
    active = true;
  }
  clearTimeout(timeout);
  timeout = setTimeout(setInactive, 10000);
}
$(window).on('keydown mousemove', setActive)
setActive()
bubble("Hello")
          runreloadreveal

variables, manual timeout mgmt, side-effects

FRP

var activityE = $(window).asEventStream('mousemove keydown')
var sleepE = activityE.merge(Bacon.once()).debounce(3000)
var activeP = activityE.map(true).merge(sleepE.map(false))
  .toProperty(true).skipDuplicates()

var wakeUpE = activeP.changes().where().equalTo(true)

sleepE.map("asleep?").show()
wakeUpE.map("back!").show()
bubble("hello")
          runreloadreveal

Bacon.js

an FRP library

Not a framework

Not a jQuery plugin

call it ~

~ is the _ of events

EventStream

Source of events

EventStream

Observable (subscribe, onValue, onError, onEnd)

EventStream

map, filter, merge, concat, flatMap

Creating streams

var singleEventStream = Bacon.once("POW")
          runreloadreveal
var singleEventStream = Bacon.once("POW"); var countdown = Bacon.sequentially(1000, [5,4,3,2,1,"POW"]); countdown.show() var keys = $(document).asEventStream("keyup") .map(function(e) { return e.keyCode }) .filter(function(key) { return key == 38 }) // UP ARROW keys.show()

keyups, map, filter "wanna see flatMap"? later, sequentialy flatmap delay throttle

Property

time-varying value

Property

Observable (subscribe, onValue, onError, onEnd)

Property

map, combine

keyUp = Event

keyState = Property

KeyState

          runreloadreveal
var keyState = keyUps(38).map(false) .merge(keyDowns(38).map(true)) .skipDuplicates() .toProperty(false) keyState.show()

Spreadsheet

+ =
          runreloadreveal
function fieldValue($field) { function currentValue() { return $field.val() } var changesE = $field.asEventStream("keyup"); return changesE.map(currentValue).toProperty(currentValue()) } var a = fieldValue($("#a")).map(parseInt); var b = fieldValue($("#b")).map(parseInt); var c = a.combine(b, function(aVal, bVal) { return aVal + bVal }) c.onValue(function(cVal) { $("#c").val(cVal) })

Shopping Cart

Add Remove Checkout
          runreloadreveal
var addE = $("#addItem").asEventStream("click") .flatMap(function() { return $("#itemName").val() }) var removeE = $("#removeItem").asEventStream("click") var contentsP = Bacon.update([], addE, function(items, newItem) { return items.concat(newItem) }, removeE, function(items) { return items.slice(1) } ) contentsP.show() var checkoutE = $("#checkout").asEventStream("click") .map(contentsP) checkoutE.onValue(function(contents) { bubble("checkout: " + contents) })

K THX BYE

Bacon.js @raimohanska