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. 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
  2. What if the user
 was a function? @andrestaltz Exploring unidirectional

    dataflow, MV*, 
 reactive and functional programming
  3. Insight #1: UIs are cycles Insight #2: UIs are functions


    Insight #3: UIs are async Insight #4: UIs are symmetric
  4. 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
  5. ?

  6. ?

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

     not  simply  write  this  function   } 1   2   3
  8. Scroll Scroll Scroll Click Scroll Scroll interactionEvents screenEvents Screen Eyes

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

    DOM Brain Hands DOM Event Dispatcher These
 are
 "remote"
  10. 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
  11. 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
  12. 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
  13. 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
  14. Definition: a fixed point of a function f(x)
 is a

    point x0 such that f(x0) = x0. Example: cos(0.73908513…) = 0.73908513…
  15. var  screenEvents  =  computer(interactionEvents);
 var  interactionEvents  =  user(screenEvents); 1  

    2 㱺 interactionsEvents needs to exist 
 before applying computer() function
  16. 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
  17. var  interactionEvents  =  makeEmptyEventStream();   
 user(computer(interactionEvents))
    .listen(function  (ev)

     {          interactionEvents.emit(ev);      }); 1   2   3   4   5   6 b = g(f(b))
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 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
  24. Cycle.applyToDOM('#app',  function  computer(interactions)  {   
 
 
 
 


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

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

  27. 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>      );
 

  28. 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
  29. 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!
  30. 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
  31. 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
  32. 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
  33. 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
  34. 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