Functional Reactive Programming

35bdded0ed436595945447a2484a77b0?s=47 febuiles
November 09, 2012

Functional Reactive Programming

Another approach to async. programming.

35bdded0ed436595945447a2484a77b0?s=128

febuiles

November 09, 2012
Tweet

Transcript

  1. Functional Reactive Programming Another approach to asynchronous systems Federico Builes

    federico@mheroin.com
  2. Functional declarative framework for processing streams of values

  3. $.ajax({ url: apiUrl, method: apiMethod, data: { artist: artist, title:

    title }, beforeSend: loader.start, success: function(data, status, jqXhr){ loader.stop(); showLyrics(); $("#set-video").show(); if (data === "Sorry, We don't have lyrics for this song yet.") { activateStep("step2-nolyrics"); } else { $("#fetch-lyrics").hide(); activateStep("step2"); } write(data); }, error: function(xhr, status, error){ loader.stop(); showLyrics(); if (artist === "" || title === "") { write("You need to enter the artist's name and the song title.") } else { write("There has been an error processing the data. Please try again."); } } });
  4. $.ajax({ url: apiUrl, method: apiMethod, data: { artist: artist, title:

    title }, beforeSend: loader.start, success: function(data, status, jqXhr){ loader.stop(); showLyrics(); $("#set-video").show(); if (data === "Sorry, We don't have lyrics for this song yet.") { activateStep("step2-nolyrics"); } else { $("#fetch-lyrics").hide(); activateStep("step2"); } write(data); }, error: function(xhr, status, error){ loader.stop(); showLyrics(); if (artist === "" || title === "") { write("You need to enter the artist's name and the song title.") } else { write("There has been an error processing the data. Please try again."); } } });
  5. $.ajax({ url: apiUrl, method: apiMethod, data: { artist: artist, title:

    title }, beforeSend: loader.start, success: function(data, status, jqXhr){ loader.stop(); showLyrics(); $("#set-video").show(); if (data === "Sorry, We don't have lyrics for this song yet.") { activateStep("step2-nolyrics"); } else { $("#fetch-lyrics").hide(); activateStep("step2"); } write(data); }, error: function(xhr, status, error){ loader.stop(); showLyrics(); if (artist === "" || title === "") { write("You need to enter the artist's name and the song title.") } else { write("There has been an error processing the data. Please try again."); } } });
  6. $.ajax({ url: apiUrl, method: apiMethod, data: { artist: artist, title:

    title }, beforeSend: loader.start, success: ajaxSuccess, error: ajaxError, });
  7. $.ajax({ url: apiUrl, method: apiMethod, data: { artist: artist, title:

    title }, beforeSend: loader.start, success: ajaxSuccess, error: ajaxError, });
  8. Continuation-passing Style (CPS)

  9. Continuation-passing style (CPS) is a style of programming in which

    control is passed explicitly in the form of a continuation.
  10. A continuation is a data structure that represents the computational

    process at a given point in the process’ execution.
  11. function id(x) { return x; } // CPS function id(x,

    cc) { cc(x); }
  12. function fact(n) { if (n == 0) return 1; else

    return n * fact(n-1); } // En CPS function fact(n, cc) { if (n == 0) cc(1); else { fact(n - 1, function (val) { cc(n * val) }); } }
  13. fact (5, function (n) { console.log(n) ; })

  14. (defun pyth (x y) (sqrt (+ (* x x) (*

    y y))))
  15. (defun cps+ (x y cc) (funcall cc (+ x y)))

    (defun cps* (x y cc) (funcall cc (* x y))) (defun sqrt*(x cc) (funcall cc (sqrt x))) (defun cps-pyth (x y cc) (cps* x x (lambda (x2) (cps* y y (lambda (y2) (cps+ x2 y2 (lambda (sum) (sqrt* sum cc)))))))) go Lisp =)
  16. add_cps :: Int -> Int -> (Int -> r) ->

    r add_cps x y k = k (x + y) square_cps :: Int -> (Int -> r) -> r square_cps x k = k (x * x) pythagoras_cps :: Int -> Int -> (Int -> r) -> r pythagoras_cps x y k = square_cps x $ \x_squared -> square_cps y $ \y_squared -> add_cps x_squared y_squared $ \sum_of_squares -> k sum_of_squares
  17. add_cps :: Int -> Int -> (Int -> r) ->

    r add_cps x y k = k (x + y) square_cps :: Int -> (Int -> r) -> r square_cps x k = k (x * x) pythagoras_cps :: Int -> Int -> (Int -> r) -> r pythagoras_cps x y k = square_cps x $ \x_squared -> square_cps y $ \y_squared -> add_cps x_squared y_squared $ \sum_of_squares -> k sum_of_squares
  18. Compilers/Analizers Flow Control Concurrency Distributed Systems

  19. Systems with inherent latency

  20. Callback Hell

  21. $.ajax({ url: apiUrl, method: apiMethod, data: { artist: artist, title:

    title }, beforeSend: loader.start, success: function(data, status, jqXhr){ loader.stop(); showLyrics(); $("#set-video").show(); if (data === "Sorry, We don't have lyrics for this song yet.") { activateStep("step2-nolyrics"); } else { $("#fetch-lyrics").hide(); activateStep("step2"); } write(data); }, error: function(xhr, status, error){ loader.stop(); showLyrics(); if (artist === "" || title === "") { write("You need to enter the artist's name and the song title.") } else { write("There has been an error processing the data. Please try again."); } } });
  22. $.ajax({ url: apiUrl, method: apiMethod, data: { artist: artist, title:

    title }, beforeSend: loader.start, success: ajaxSuccess, error: ajaxError, });
  23. $.ajax({ url: apiUrl, method: apiMethod, data: { artist: artist, title:

    title }, beforeSend: loader.start, success: ajaxSuccess, error: ajaxError, });
  24. $ ack "\.ajax\({" | wc -l 48 $ find .

    -name *.js | xargs cat | wc -l 1019
  25. goto : structured programming :: callbacks : async programming

  26. Functional Reactive Programming

  27. Functional Reactive Programming

  28. None
  29. Functional Reactive Programming

  30. Behaviors (signals) Reactive values that change over time

  31. Behavior a = Time ! a The value of behavior

    s on the time t is s(t)
  32. Event Sequences of occurrences of events over time

  33. Event a = Time × a Pairs: (time, event occurrence

    information)
  34. leftClick :: Event () keyPress :: Event Char

  35. red :: Behavior Color 1 :: Behavior Real Behaviors Constantes

  36. time :: Behavior Time Behaviors Variables *

  37. -=> :: Eventα -> β -> Eventβ color :: Behavior

    Color color = red `until` (leftClick -=> blue) circ :: Behavior Region circ = translate (cos time, sin time) (circle 1) ball :: Behavior Picture ball = paint color circ
  38. None
  39. def follow res = write_to_db res = notify_user(res) return update_ui(res)

    end def write_to_db # ... end def notify_user # ... end def update_ui # ... end blocking
  40. def follow write_to_db.callback do |a| notify_user(a).callback do |b| update_ui(b).callback do

    |resp| puts resp end end end end async
  41. # follow es el evento def follow tie(:write_to_db, :notify_user, :update_ui)

    end reactive
  42. References •Gerald Jay Sussman and Guy L. Steele, Jr. "Scheme:

    An interpreter for extended lambda calculus". AI Memo 349: 19, December 1975. •Edsger W. Dijkstra. Go To Statement Considered Harmful. Communications of the ACM, Vol. 11, No. 3, March 1968, pp. 147-148. •Conal Elliott and Paul Hudak. "Functional Reactive Animation". ICFP 1997. http:// conal.net/papers/icfp97/. •Zhanyong Wan and Paul Hudak. "Functional Reactive Programming from First Principles". In ACM SIGPLAN Conference on Programming Language Design and Implementation, pp. 242-252, 2000. •Conal Elliott, "Push-Pull Functional Reactive Programming". Haskell Symposium, 2009. http://conal.net/papers/push-pull-frp/push-pull-frp.pdf. Video: http://www.vimeo.com/ 6686570 •http://elm-lang.org/learn/What-is-FRP.elm •http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style