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.

C8dbe3c6d219999ee0ecce86a450d0e3?s=128

André Staltz

May 14, 2015
Tweet

Transcript

  1. “Easier to reason about”

  2. Reactive programming

  3. Virtual DOM

  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
  5. Golden ratio

  6. Golden ratio Natural Beautiful Complex

  7. Equivalent
 in JavaScript
 UIs?

  8. What if the user
 was a function? @andrestaltz Exploring unidirectional

    dataflow, MV*, 
 reactive and functional programming
  9. None
  10. Human Computer

  11. Interface

  12. Insight #1: UIs are cycles

  13. “Output device” “Input device”

  14. Function f Input Output x f(x)

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

  16. Blocking UIs

  17. Non-blocking UIs

  18. js jscon jsconf jsconf budap jsonline
 jstor js.com.ph
 jsconsole jsconf

    2014
 jsconf 2015 jsconf budapest Computer
  19. a•syn•chro•nous adj. Not synchronous; occurring at different times. adj. Allows

    the other to continue during processing.
  20. Insight #1: UIs are cycles Insight #2: UIs are functions


    Insight #3: UIs are async
  21. Interface

  22. Interface Senses Expression

  23. Expression Senses Expression Senses Symmetry

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


    Insight #3: UIs are async Insight #4: UIs are symmetric
  25. Output Input Output Input Symmetry

  26. Input Output

  27. User Scroll Scroll Scroll Click Scroll Scroll

  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
  29. How to code this?

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

  31. ?

  32. ?

  33. [2,  4,  6] ?

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

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

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

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

  38. time Things happening at certain times

  39. time Events! Event Stream

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

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

  42. merge

  43. window

  44. combineLatest

  45. withLatestFrom

  46. flatMap( )

  47. Computer jsconfbp.com interactionEvents screenEvents

  48. function  computer(x:  EventStream<String>):  EventStream<Screen>  {      //  ...  

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

      1   2
  50. User Scroll Scroll Scroll Click Scroll Scroll interactionEvents screenEvents

  51. function  user(screenEvents:  EventStream):  EventStream  {      //  one  does

     not  simply  write  this  function   } 1   2   3
  52. Scroll Scroll Scroll Click Scroll Scroll interactionEvents screenEvents User

  53. Scroll Scroll Scroll Click Scroll Scroll interactionEvents screenEvents Screen Eyes

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

    DOM Brain Hands DOM Event Dispatcher These
 are all 
 we need
  55. Scroll Scroll Scroll Click Scroll Scroll interactionEvents screenEvents Screen Eyes

    DOM Brain Hands DOM Event Dispatcher These
 are
 "remote"
  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
  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
  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
  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
  60. var  interactionEvents  =  user(screenEvents);   interactionEvents.listen(function  (ev)  {  ...  });

      1   2
  61. var  screenEvents  =  computer(interactionEvents);
 var  interactionEvents  =  user(screenEvents); 1  

    2 Equivalent to…
  62. var  a  =  f(b);
 var  b  =  g(a); 1  

    2
  63. var  a  =  f(b);
 var  b  =  g(a); 1  

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

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

    types of “=”?
  66. b = g(f(b))

  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…
  68. Problem: Find screenEvents such that screenEvents = computer(user(screenEvents).

  69. var  screenEvents  =  computer(interactionEvents);
 var  interactionEvents  =  user(screenEvents); 1  

    2 㱺 interactionsEvents needs to exist 
 before applying computer() function
  70. var  interactionEvents  =  makeEmptyEventStream();   var  screenEvents  =  computer(interactionEvents);
 var

     interactionEvents2  =  user(screenEvents); 1   2   3   4
  71. var  interactionEvents  =  makeEmptyEventStream();   var  screenEvents  =  computer(interactionEvents);
 var

     interactionEvents2  =  user(screenEvents); 1   2   3   4
  72. var  interactionEvents  =  makeEmptyEventStream();   var  screenEvents  =  computer(interactionEvents);
 var

     interactionEvents2  =  user(screenEvents); 1   2   3   4
  73. First screen Computer User interactionEvents interactionEvents2 screenEvents

  74. Computer User interactionEvents interactionEvents2 screenEvents

  75. Computer User interactionEvents interactionEvents2 screenEvents

  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
  77. var  interactionEvents  =  makeEmptyEventStream();   var  screenEvents  =  computer(interactionEvents);
 user(screenEvents).listen(function

     (ev)  {      interactionEvents.emit(ev);   }); 1   2   3   4   5   6
  78. var  interactionEvents  =  makeEmptyEventStream();   
 user(computer(interactionEvents))
    .listen(function  (ev)

     {          interactionEvents.emit(ev);      }); 1   2   3   4   5   6 b = g(f(b))
  79. Solved!

  80. Computer

  81. Computer Huge!

  82. Updates Manipulates Manipulates Sees Uses     

     
  83. None
  84. Model View User ???

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

  86. Model View User ??? Information User language

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

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

    language
  89. Computer

  90. Intent View Model or…

  91. function function or…

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

  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
  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
  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
  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
  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
  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
  100. applyToDOM(container,  computerFn)
 registerCustomElement(tagName,  definitionFn) Cycle.js API

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


    
 
 
 
 
 
 }); 1   2   3   4   5   6   7   8   9
 10
 11
 12
 13
  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);   
 
 
 
 
 
 
 
 

  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('');
 
 
 
 
 
 
 
 

  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  =>
        <div>              <label>Name</label>              <input  className="field"  type="text"/>              <h1>Hello  {name}</h1>          </div>      );
 

  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  =>
        <div>              <label>Name</label>              <input  className="field"  type="text"/>              <h1>Hello  {name}</h1>          </div>      );
    return  screen$;
 }); 1   2   3   4   5   6   7   8   9
 10
 11
 12
 13
  107. Cycle.applyToDOM('#app',  function  computer(interactions)  {      return  interactions.get('.field',  'input')  

           .map(ev  =>  ev.target.value)          .startWith('')          .map(name  =>
            <div>                  <label>Name</label>                  <input  className="field"  type="text"/>                  <h1>Hello  {name}</h1>              </div>          );
 }); 1   2   3   4   5   6   7   8   9
 10
 11
 12 From keyboard… to screen!
  108. Computer

  109. Intent View Model

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

       .map(ev  =>  ev.target.value);   } 1   2   3   4
  111. function  model(changeName$)  {      return  Rx.Observable.just('').merge(changeName$);   } 1

      2   3
  112. function  view(name$)  {      return  name$.map(name  =>  (  

           <div>              <label>Name</label>              <input  className="field"  type="text"/>              <h1>Hello  {name}</h1>          </div>      ));   } 1   2   3   4   5   6   7   8   9
  113. function  computer(interactions)  {      return  view(model(intent(interactions)));   } 1


    2
 3
  114. Computer You choose or…

  115. function function or…

  116. Intent View Model

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

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

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

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

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

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

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

  124. function  view(name$)  {      return  name$.map(name  =>  (  

           <div>              <label>Name</label>              <input  className="field"  type="text"/>              <h1>Hello  {name}</h1>          </div>      ));   } 1   2   3   4   5   6   7   8   9
  125. 1   2   3   4   5  

    6   7   8   9 function  view(name$)  {      return  name$.map(name  =>  (          <div>              <label>Name</label>              <input  className="field"  type="text"/>              <h1>Hello  {name}</h1>          </div>      ));   } Virtual DOM
  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
  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
  128. Human Computer

  129. Human Human ?

  130. Expression Senses Expression Senses

  131. Expression Senses Expression Senses

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

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

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

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

    What’s up? good! Conversation
  136. Thank you @andrestaltz