Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What if the user was a function?

What if the user was a function?

An exploration of the true nature of user interfaces, and a cyclic async functional architecture which captures the essence of UIs and any other form of interaction.

André Staltz

May 14, 2015
Tweet

More Decks by André Staltz

Other Decks in Programming

Transcript

  1. “Easier to reason about”

    View Slide

  2. Reactive programming

    View Slide

  3. Virtual DOM

    View Slide

  4. Unidirectional dataflow
    Functional reactive programming
    Immutable data structures
    Virtual DOM
    One-way data binding Dispatcher
    Flux
    Cursors
    Shadow DOM
    Components
    State and props
    Purity
    JavaScript in 2015
    Declarative
    Isomorphic

    View Slide

  5. Golden ratio

    View Slide

  6. Golden ratio
    Natural
    Beautiful
    Complex

    View Slide

  7. Equivalent

    in JavaScript

    UIs?

    View Slide

  8. What if the user

    was a function?
    @andrestaltz
    Exploring unidirectional dataflow, MV*, 

    reactive and functional programming

    View Slide

  9. View Slide

  10. Human
    Computer

    View Slide

  11. Interface

    View Slide

  12. Insight #1: UIs are cycles

    View Slide

  13. “Output device” “Input device”

    View Slide

  14. Function f
    Input
    Output
    x
    f(x)

    View Slide

  15. Insight #1: UIs are cycles
    Insight #2: UIs are functions

    View Slide

  16. Blocking UIs

    View Slide

  17. Non-blocking UIs

    View Slide

  18. js jscon jsconf jsconf budap
    jsonline

    jstor
    js.com.ph

    jsconsole
    jsconf 2014

    jsconf 2015
    jsconf budapest
    Computer

    View Slide

  19. a•syn•chro•nous
    adj. Not synchronous; occurring at different times.
    adj. Allows the other to continue during processing.

    View Slide

  20. Insight #1: UIs are cycles
    Insight #2: UIs are functions

    Insight #3: UIs are async

    View Slide

  21. Interface

    View Slide

  22. Interface
    Senses Expression

    View Slide

  23. Expression Senses
    Expression
    Senses
    Symmetry

    View Slide

  24. Insight #1: UIs are cycles
    Insight #2: UIs are functions

    Insight #3: UIs are async
    Insight #4: UIs are symmetric

    View Slide

  25. Output Input
    Output
    Input
    Symmetry

    View Slide

  26. Input
    Output

    View Slide

  27. User
    Scroll
    Scroll
    Scroll
    Click
    Scroll
    Scroll

    View Slide

  28. Insight #1: UIs are cycles
    Insight #2: UIs are functions

    Insight #3: UIs are async
    Insight #4: UIs are symmetric
    Insight #5: The User is a function

    View Slide

  29. How to code this?

    View Slide

  30. Computer
    jsconfbp.com
    Given URL…
    …render website.

    View Slide

  31. ?

    View Slide

  32. ?

    View Slide

  33. [2,  4,  6]
    ?

    View Slide

  34. [2,  4,  6]
    map(x  =>  10*x)
    [20,  40,  60]

    View Slide

  35. [2,  4,  6]
    filter(x  =>  x  <  5)
    [2,  4]

    View Slide

  36. map(x&=>&10*x)
    2
    20 40 60
    4 6

    View Slide

  37. filter(x)=>)x)<)5)
    2
    2 4
    4 6

    View Slide

  38. time
    Things happening at certain times

    View Slide

  39. time
    Events!
    Event Stream

    View Slide

  40. Array: sequence over space.
    Event Stream: sequence over time.

    View Slide

  41. delay
    2 4 6 8
    2 4 6 … ∞

    View Slide

  42. merge

    View Slide

  43. window

    View Slide

  44. combineLatest

    View Slide

  45. withLatestFrom

    View Slide

  46. flatMap( )

    View Slide

  47. Computer
    jsconfbp.com
    interactionEvents
    screenEvents

    View Slide

  48. function  computer(x:  EventStream):  EventStream  {  
       //  ...  
    }
    1  
    2  
    3

    View Slide

  49. var  screenEvents  =  computer(interactionEvents);  
    screenEvents.listen(function  (ev)  {  ...  });  
    1  
    2

    View Slide

  50. User
    Scroll
    Scroll
    Scroll
    Click
    Scroll
    Scroll interactionEvents
    screenEvents

    View Slide

  51. function  user(screenEvents:  EventStream):  EventStream  {  
       //  one  does  not  simply  write  this  function  
    }
    1  
    2  
    3

    View Slide

  52. Scroll
    Scroll
    Scroll
    Click
    Scroll
    Scroll interactionEvents
    screenEvents
    User

    View Slide

  53. Scroll
    Scroll
    Scroll
    Click
    Scroll
    Scroll interactionEvents
    screenEvents
    Screen Eyes
    DOM Brain Hands
    DOM Event Dispatcher

    View Slide

  54. Scroll
    Scroll
    Scroll
    Click
    Scroll
    Scroll interactionEvents
    screenEvents
    Screen Eyes
    DOM Brain Hands
    DOM Event Dispatcher
    These

    are all 

    we need

    View Slide

  55. Scroll
    Scroll
    Scroll
    Click
    Scroll
    Scroll interactionEvents
    screenEvents
    Screen Eyes
    DOM Brain Hands
    DOM Event Dispatcher
    These

    are

    "remote"

    View Slide

  56. function  user(screenEvents:  EventStream):  EventStream  {  
       screenEvents.listen(function  (screen)  {  
           renderToDOM(screen);  
       });  
       var  interactionEvents  =  new  EventStream();

       document.addEventListener("*",  function  (ev)  {

           interactionEvents.emit(ev);  
       });

       return  interactionEvents;

    }
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9  
    10

    View Slide

  57. function  user(screenEvents:  EventStream):  EventStream  {  
       screenEvents.listen(function  (screen)  {  
           renderToDOM(screen);  
       });  
       var  interactionEvents  =  new  EventStream();

       document.addEventListener("*",  function  (ev)  {

           interactionEvents.emit(ev);  
       });

       return  interactionEvents;

    }
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9  
    10

    View Slide

  58. function  user(screenEvents:  EventStream):  EventStream  {  
       screenEvents.listen(function  (screen)  {  
           renderToDOM(screen);  
       });  
       var  interactionEvents  =  new  EventStream();

       document.addEventListener("*",  function  (ev)  {

           interactionEvents.emit(ev);  
       });

       return  interactionEvents;

    }
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9  
    10

    View Slide

  59. function  user(screenEvents:  EventStream):  EventStream  {  
       screenEvents.listen(function  (screen)  {  
           renderToDOM(screen);  
       });  
       var  interactionEvents  =  new  EventStream();

       document.addEventListener("*",  function  (ev)  {

           interactionEvents.emit(ev);  
       });

       return  interactionEvents;

    }
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9  
    10

    View Slide

  60. var  interactionEvents  =  user(screenEvents);  
    interactionEvents.listen(function  (ev)  {  ...  });  
    1  
    2

    View Slide

  61. var  screenEvents  =  computer(interactionEvents);

    var  interactionEvents  =  user(screenEvents);
    1  
    2
    Equivalent to…

    View Slide

  62. var  a  =  f(b);

    var  b  =  g(a);
    1  
    2

    View Slide

  63. var  a  =  f(b);

    var  b  =  g(a);
    1  
    2

    View Slide

  64. var  b  =  g(f(b));
    1
    Problem!

    View Slide

  65. var  b  ←  g(f(b));
    1
    “=” is assignment!
    What other types of “=”?

    View Slide

  66. b = g(f(b))

    View Slide

  67. Definition: a fixed point of a function f(x)

    is a point x0 such that f(x0) = x0.
    Example: cos(0.73908513…) = 0.73908513…

    View Slide

  68. Problem: Find screenEvents such that
    screenEvents = computer(user(screenEvents).

    View Slide

  69. var  screenEvents  =  computer(interactionEvents);

    var  interactionEvents  =  user(screenEvents);
    1  
    2
    㱺 interactionsEvents needs to exist 

    before applying computer() function

    View Slide

  70. var  interactionEvents  =  makeEmptyEventStream();  
    var  screenEvents  =  computer(interactionEvents);

    var  interactionEvents2  =  user(screenEvents);
    1  
    2  
    3  
    4

    View Slide

  71. var  interactionEvents  =  makeEmptyEventStream();  
    var  screenEvents  =  computer(interactionEvents);

    var  interactionEvents2  =  user(screenEvents);
    1  
    2  
    3  
    4

    View Slide

  72. var  interactionEvents  =  makeEmptyEventStream();  
    var  screenEvents  =  computer(interactionEvents);

    var  interactionEvents2  =  user(screenEvents);
    1  
    2  
    3  
    4

    View Slide

  73. First screen
    Computer
    User
    interactionEvents
    interactionEvents2
    screenEvents

    View Slide

  74. Computer
    User
    interactionEvents
    interactionEvents2
    screenEvents

    View Slide

  75. Computer
    User
    interactionEvents
    interactionEvents2
    screenEvents

    View Slide

  76. var  interactionEvents  =  makeEmptyEventStream();  
    var  screenEvents  =  computer(interactionEvents);

    var  interactionEvents2  =  user(screenEvents);  
    interactionEvents2.listen(function  (ev)  {  
       interactionEvents.emit(ev);  
    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8

    View Slide

  77. var  interactionEvents  =  makeEmptyEventStream();  
    var  screenEvents  =  computer(interactionEvents);

    user(screenEvents).listen(function  (ev)  {  
       interactionEvents.emit(ev);  
    });
    1  
    2  
    3  
    4  
    5  
    6

    View Slide

  78. var  interactionEvents  =  makeEmptyEventStream();  

    user(computer(interactionEvents))

       .listen(function  (ev)  {  
           interactionEvents.emit(ev);  
       });
    1  
    2  
    3  
    4  
    5  
    6
    b = g(f(b))

    View Slide

  79. Solved!

    View Slide

  80. Computer

    View Slide

  81. Computer
    Huge!

    View Slide

  82. Updates Manipulates
    Manipulates
    Sees Uses






    View Slide

  83. View Slide

  84. Model
    View
    User
    ???

    View Slide

  85. Model
    View
    User
    ???
    01010001010110101
    What’s up? ❤

    View Slide

  86. Model
    View
    User
    ???
    Information
    User language

    View Slide

  87. Model
    View
    User
    ???
    Information
    User language
    New information
    User language

    View Slide

  88. Model
    View
    User
    Intent
    Information
    User language
    New information
    User language

    View Slide

  89. Computer

    View Slide

  90. Intent
    View
    Model
    or…

    View Slide

  91. function
    function
    or…

    View Slide

  92. View Slide

  93. https://github.com/staltz/cycle
    Cycle.js
    Powered by RxJS

    View Slide

  94. var  interactionEvents  =  makeEmptyEventStream();  
    var  screenEvents  =  computer(interactionEvents);

    var  interactionEvents2  =  user(screenEvents);  
    interactionEvents2.listen(function  (ev)  {  
       interactionEvents.emit(ev);  
    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8

    View Slide

  95. var  interactionEvents  =  makeEmptyEventStream();  
    var  screenEvents  =  computer(interactionEvents);

    var  interactionEvents2  =  user(screenEvents);  
    interactionEvents2.listen(function  (ev)  {  
       interactionEvents.emit(ev);  
    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8
    Boilerplate

    View Slide

  96. var  interactionEvents  =  makeEmptyEventStream();  
    var  screenEvents  =  computer(interactionEvents);

    var  interactionEvents2  =  user(screenEvents);  
    interactionEvents2.listen(function  (ev)  {  
       interactionEvents.emit(ev);  
    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8
    Mutation

    View Slide

  97. var  interactionEvents  =  makeEmptyEventStream();  
    var  screenEvents  =  computer(interactionEvents);

    var  interactionEvents2  =  user(screenEvents);  
    interactionEvents2.listen(function  (ev)  {  
       interactionEvents.emit(ev);  
    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8
    Proxy stream and real stream

    View Slide

  98. var  interactionEvents  =  makeEmptyEventStream();  
    var  screenEvents  =  computer(interactionEvents);

    var  interactionEvents2  =  user(screenEvents);  
    interactionEvents2.listen(function  (ev)  {  
       interactionEvents.emit(ev);  
    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8

    View Slide

  99. var  interactionEvents  =  makeEmptyEventStream();  
    var  screenEvents  =  computer(interactionEvents);

    var  interactionEvents2  =  user(screenEvents);  
    interactionEvents2.listen(function  (ev)  {  
       interactionEvents.emit(ev);  
    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8
    Only this matters to you

    View Slide

  100. applyToDOM(container,  computerFn)

    registerCustomElement(tagName,  definitionFn)
    Cycle.js API

    View Slide

  101. View Slide

  102. Cycle.applyToDOM('#app',  function  computer(interactions)  {  











    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9

    10

    11

    12

    13

    View Slide

  103. Cycle.applyToDOM('#app',  function  computer(interactions)  {  
     











    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9

    10

    11

    12

    13
       var  changeName$  =  interactions.get('.field',  'input')  
           .map(ev  =>  ev.target.value);  









    View Slide

  104. Cycle.applyToDOM('#app',  function  computer(interactions)  {  
       var  changeName$  =  interactions.get('.field',  'input')  
           .map(ev  =>  ev.target.value);










    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9

    10

    11

    12

    13
     

       var  name$  =  changeName$.startWith('');









    View Slide

  105. Cycle.applyToDOM('#app',  function  computer(interactions)  {  
       var  changeName$  =  interactions.get('.field',  'input')  
           .map(ev  =>  ev.target.value);

       var  name$  =  changeName$.startWith('');









    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9

    10

    11

    12

    13
     

       

       var  screen$  =  name$.map(name  =>

             
               Name  
                 
               Hello  {name}  
             
       );


    View Slide

  106. Cycle.applyToDOM('#app',  function  computer(interactions)  {  
       var  changeName$  =  interactions.get('.field',  'input')  
           .map(ev  =>  ev.target.value);  
       var  name$  =  changeName$.startWith('');  
       var  screen$  =  name$.map(name  =>

             
               Name  
                 
               Hello  {name}  
             
       );

       return  screen$;

    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9

    10

    11

    12

    13

    View Slide

  107. Cycle.applyToDOM('#app',  function  computer(interactions)  {  
       return  interactions.get('.field',  'input')  
           .map(ev  =>  ev.target.value)  
           .startWith('')  
           .map(name  =>

                 
                   Name  
                     
                   Hello  {name}  
                 
           );

    });
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9

    10

    11

    12 From keyboard… to screen!

    View Slide

  108. Computer

    View Slide

  109. Intent
    View
    Model

    View Slide

  110. function  intent(interactions)  {  
       return  interactions.get('.field',  'input')

           .map(ev  =>  ev.target.value);  
    }
    1  
    2  
    3  
    4

    View Slide

  111. function  model(changeName$)  {  
       return  Rx.Observable.just('').merge(changeName$);  
    }
    1  
    2  
    3

    View Slide

  112. function  view(name$)  {  
       return  name$.map(name  =>  (  
             
               Name  
                 
               Hello  {name}  
             
       ));  
    }
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9

    View Slide

  113. function  computer(interactions)  {  
       return  view(model(intent(interactions)));  
    }
    1

    2

    3

    View Slide

  114. Computer
    You choose
    or…

    View Slide

  115. function
    function
    or…

    View Slide

  116. Intent
    View
    Model

    View Slide

  117. model()
    view()
    user()
    intent()

    View Slide

  118. model()
    view()
    user()
    intent()
    name$
    screen$ interactions
    changeName$

    View Slide

  119. model()
    view()
    user()
    intent()
    name$
    vtree$ interaction$
    changeName$
    Unidirectional data flow

    View Slide

  120. [2,  4,  6]
    map(x  =>  10*x)
    [20,  40,  60]

    View Slide

  121. [2,  4,  6]
    map(x  =>  10*x)
    [20,  40,  60]
    Functional programming
    Immutability

    View Slide

  122. filter(x)=>)x)<)5)
    2
    2 4
    4 6

    View Slide

  123. filter(x)=>)x)<)5)
    2
    2 4
    4 6
    Reactive programming

    View Slide

  124. function  view(name$)  {  
       return  name$.map(name  =>  (  
             
               Name  
                 
               Hello  {name}  
             
       ));  
    }
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9

    View Slide

  125. 1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9
    function  view(name$)  {  
       return  name$.map(name  =>  (  
             
               Name  
                 
               Hello  {name}  
             
       ));  
    }
    Virtual DOM

    View Slide

  126. Unidirectional dataflow
    Functional reactive programming
    Immutable data structures
    Virtual DOM
    One-way data binding Dispatcher
    Flux
    Cursors
    Shadow DOM
    Components
    State and props
    Purity
    Not that scary…
    Declarative
    Isomorphic

    View Slide

  127. Insight #1: UIs are cycles
    Insight #2: UIs are functions

    Insight #3: UIs are async
    Insight #4: UIs are symmetric
    Insight #5: The User is a function

    View Slide

  128. Human
    Computer

    View Slide

  129. Human
    Human
    ?

    View Slide

  130. Expression Senses
    Expression
    Senses

    View Slide

  131. Expression Senses
    Expression
    Senses

    View Slide

  132. Alice
    What’s up?
    Fine! And you?

    View Slide

  133. What’s up? Good!
    Fine! And you?
    Fine! And you?
    Bob
    Alice

    View Slide

  134. merge
    What’s up? Good!
    Fine! And you?
    Fine! And you?
    What’s up? Good!

    View Slide

  135. merge
    What’s up? good!
    Fine! And you?
    Fine! And you?
    What’s up? good!
    Conversation

    View Slide

  136. Thank you
    @andrestaltz

    View Slide