Andre Staltz: What if the user was a function?
[32:19]
transcript
yeah cool right have you seen this diagram before this particular diagram does anyone know what the name of this is yeah um so it's supposed to make user interfaces very easy right instead of model view controller you have actions and dispatcher and action creators and and and store and Views and view controls and some other stuff right so what about this diagram do you recognize this um it's supposed to make a vent driven program somehow you know composable or uh observable and finally now you have propagation of change I mean what what does that mean and this thing here now that you know we have diff and patch and sort of virtual data structures finally uis are declarative right of obviously so virtual becomes declarative I mean why this is the state of JavaScript in 2015 uh like what happened here you know are we over engineering our apps or how we actually found a better way of building stuff and if it's better then why is there so much to learn I mean why is why why isn't better simp and why isn't better sort of like more obvious for us that over there is a sunflower and the the center part of the sunflower has these seeds that form this beautiful pattern which is actually governed by the Golden Ratio so think about the golden ratio for a while 1.618 033 Etc sounds like an arbitrary sort of madeup number but actually occurs in nature and it creates these things like this so what if there would be some something like this for JavaScript so a pattern which is natural it just happens to be there um but it's still sort of beautiful and complex and you you can understand it so I've been studying how to apply reactive and functional programming for user interfaces and I stumbled upon this interesting architecture which I want to share with you today have you tried already virtual reality so first time I tried it there was this demo see you just see the table and some objects on the table and the first thing you you feel is like I want to touch this and it's it's it's kind of so engaging as like your favorite single player campaign game where it's not a story it's not a movie it's real interaction you feel like you're there so why does this happen what is going on here so this is called user um no sorry human computer interaction so like a conversation is both parties listen and speak so if we zoom into the computer what will we see well this the desktop Tower or the processing unit and in between we have this thing called interface which is normally comprised of the screen and the mouse and the keyboard these kind of things now notice there's this cycle structure where information is inside the computer it goes onto the screen you see that with your eyes and you decide to do something with your hands on the mouse and keyboard that triggers another change to the computer and that generates another screen and it keeps on going so all user interfaces can be expressed as Cycles this is our first Insight when we're trying to find a interesting and natural architecture and actually I challenge you to find a UI that doesn't work on the low level as a cycle so in this system the interface devices are often called input device and output device right the graphics you know Graphics output and that kind of stuff so whenever you have an input and an output what do you have in between what is the best candidate yeah a function right so X is your mouse and your screen is f ofx so UI as function so the computer's role should just be a function right whatever you put on the keyboard uh and the screen should be your output as a function so remember remember the terminal programs that sort of prompt for your input these were blocking your eyes so the computer will do nothing until you do something and modern uis are not like this anymore instead they are non-blocking so with this autocomplete field the computer is simultaneously processing while U you are typing so there's no need to sort of wait until the user end that that just doesn't exist so if we would draw these events happening on timelines this is roughly what we would see U the top timeline is what you input and it runs in parallel to the bottom timeline although the bottom timeline is a function of the top one there is no such idea as wait or you know wait until the other side stop stops and this so happens to be the definition of a synchronous it's whenever one side is allowed to continue its processing regardless of what the other side is doing so that's another one that uis are asynchronous by nature or should be we don't want block blocking your eyes what else so the computer has all these kind of devices to make um its interface but what about you as the user don't you have your biological devices for instance your eyes and your hands right those are sort of your devices one of them is part of your senses and the other one is your instrument of expression now your devices are connected to the computer's devices right your your eyes are sort of looking to the screen so but isn't the computer um doesn't have also senses for instance the mouse is how the computer senses the outside world and the computer's ears would be its microphone and also the computer screen is how the computer sort of expresses its own feelings or opinions right so there's a symmetry here where both sides have senses and both sides have expression and that's another Insight the uis are symmetric with the user so the computer symmetric with the user and if they are symmetric then just as the computer has an input device and out and an output device so do you have an input device your eyes and an output device your hands whenever you have an input and an output what do you have in between a function so now your brain is a function now this is a bit philosophical because are you a referentially transparent function are you non-deterministic if you would see the same screen at the same time at the same place would you do the same thing now we don't really need to answer that question we don't need to worry about that why because you don't have a time machine you can't go back in the past we cannot go and check if you would actually do the same thing so we can just assume that yeah let's assume that you're going to do the same thing if we would go back in time so you are sort of deterministic and this is what you do as a function when you see JSC Buddha side JSC Buddha pest side yeah you emit some scroll events as your output and you see something interesting you click on it so the input is what you see from the computer and the output is what you do with your hands so let's try to explore the final Insight that the user could be a function as well that's our we have now nice five insights to build something but we have Sublime Text open and all that was interesting and nice philosophy but how do we get code in some actual JavaScript so let's start with a relatively easy one probably the smartest people in this room can make a function that given uh string of the URL renders um as an output the screen of the website but it's not a function from a string to a screen why because that would be a blocking function it would be you know we don't want to do that so it's a function from that weird Arrow to this weird Arrow so what are these Arrow thingies well to me they kind of look like fruit scers or you know well yeah sorry um so how could we express these food sticks in JavaScript well we have the first cucumber and first tomatoes second cucumber Etc these are sequences so we could probably use an array right that's what JavaScript gives us for basic sequences and arrays in JavaScript has have these functions sort of map so here we are multiplying each item by 10 and we also have filter is a function over arrays which is kind of like removing an item except we are creating a new array instead of changing the previous one so it does look like our fruit scers could have this map function right I don't see a big challenge in doing this and they could easily also have a filter function but there is a big problem why uh these things cannot be erased is because of this Arrow meaning time right and these dots are just things happening which is the definition of an event so our fruit sticks are kind of you know event streams that's what they are what's the difference with array well an array is a sequence in space and an event stream is basically sequence in time and for sequences in time you can do fancier things that arrays cannot do for instance you can delay each item by 1 second and also uh event streams can be infinite so there will always be the next hour from now even if the planet stops existing while arrays have to be finite and not just delay but you have many other functions like merge and window and combine latest and with latest from and flat map so now we know that the computer uh is not a function from a string to a screen it's a function from an event stream of string to an event stream of screen and we could name the top one as interaction events is whatever you do as a user and the bottom one is screen events is whatever the computer generates so if we would write in JavaScript actually typescript here just to show the types this is roughly how we would get started and we just need to fill in what happens inside the function so all event streams have this listen method which is really what you expect it to be it's kind of like ad event listener for clicks so no mystery on this part now the user function will do the opposite right as we saw it will take the screen events as input and it will generate interaction events as output but how can you write this in JavaScript right we need your we would need your brain for that so no can do so we can actually decompose the user function into smaller functions first this screen event is rendered is put to the Dom and the Dom with the browser shows that on the physical screen that goes to your eyes and then your eyes and the signal to your brain and your brain takes some time deciding what to do and then finally you decide okay I'm I'm going to click that and that triggers an event on the Dom event dispatcher so we only need to care about the beginning and the end which is the Dom right the Dom will be the ambassador for our user or the proxy for our user and the other functions are just living in another world than JavaScript so they're still part of our user function but we don't have direct access to them it's as if you know they were living on some remote server and we're using the Dom as the client to access that so in JavaScript it would look like this we um first start with this given screen event stream and we can listen to each screen event and render that to the Dom somehow then we create an a plain empty uh event stream called interaction events which is what we will return at the bottom of the function so then we listen to all possible events happening on the dawn so this star there doesn't actually exist it's just to illustrate our idea and this probably is not performant either but it's just to show you that we can write this function and so we whatever we listen to anything we just uh forward that to interaction events so and we're done so the user function is written and we can also listen to what it what it outputs now if you put both function applications together you get this and now we have kind of like a serious problem because um well if you can't see the problem I'm going to rename these so it's it's it's easier to see can you see it now well if we replace a with f of B on the second line you get this and now you can see the problem because B is undefined on the right hand side so we just can't do this it's because this equal symbols means assignment right that's where a complication is coming from you can't aign from think that doesn't ex you know yeah so we have other types of equals in JavaScript so inance double equals and triple equals so the equal symbols in mathematics means an equation so what if we just forget assignment and think of an equation to solve this and this is actually a special type of of equation because it's a fixed point that over there is the definition of a fixed point it's whenever X is f ofx and it's pretty common in mathematics like the co cosine has one so what if our problem would be actually to discover this the vream that satisfies this equation so let's forget assignment and since instead consider equality let's use mathematics as an inspiration so we're back into the dangerous unmalted will not help us here the complication actually is that well the second line doesn't have a problem at all but the first line has a problem because it needs to exist before we call this computer function so what if we just do that like with this line we declare interaction events as an empty event stream what is an empty event stream is just an empty fruit scre with nothing on it quite uninteresting and then now that it's available we can call the computer function on it and we get this screen events as output naturally now that screen events is available we can uh apply the user function on it and we get interaction events to a second one so what have we just achieved with this piece of code well when we called the computer function on an empty event stream we got this uh screen events which by the way starts with this default screen why because well if you don't interact with the computer at least you see this login screen so and then now we appli the screen events on the user and we got this real uh interaction events coming from the real user but we have these two um interaction events so we just need to sort of copy paste whatever happens on the bottom one back into the first one so with this whenever an event happens on the second it will be replicated back into the first and then we have sort of closed loop so in JavaScript this would be actually about listening to whatever happens on the second and just forwarding that to the first and we can also simplify this code by getting rid of um intermediate varibles so this is not a scary operation okay um no magic and we can do that again with screen events and we get this so hopefully now you see something that looks like a fixed point right I mean you can compare B with interaction events and you can compare GFF with user computer and it's solved right it wasn't that hard after all but there's something that still annoys me with this computer function because in reality it would be a huge function so in a real JavaScript application this would be thousands of lines of code because it should do networking and rendering and calculations and whatnot so how can we improve on this so mot view controller is older than I am so it's been around since the' 70s and ' 80s uh and this is the rough this is roughly the same diagram from the ' 80s I didn't really change this and there's two things I really like about this diagram and first of all is the user so with all these fancy architectures for user interfaces we kind of forgot where does the user plug in into our system right so I like it that that is here and we should probably do this more often the other thing that I like about this diagram is that it almost looks like that cyc cycle diagram that we saw some minutes ago right except there's one big difference is that there's no Arrow from the mouse to the screen while there is an arrow from a controller to a view so MVC is not a perfect cycle and we just can't name this MVC but it does look like those could correspond to model view and user but then we don't know how to name the mouse because he's the complicated bit it cannot be named controller so do you know what was the original idea in MVC and small talk forgetting all the routes and backends and stuff um it was actually in their words to bridge the gap between the digital information in the computer and the user's mental model that's what they said so the computer speaks bits zeros and ones and bites and you speak English Hungarian and cat pictures so that's what the view does right it translates from zeros and ones to English and cat pictures right if we're talking about two languag and and The View just should just bridge that gap for you so why not the other direction should just be translating from cat pictures back into something that the computer appreciates right you're giving sort of you're making a request to change something in the computer and you're giving that in sort of human terms mouse and keyboard and whatnot so I call this thing intent but you can name it whatever else you want I just like this name because it means an in in uh an interpretation of what the user is trying to achieve in the context of the digital information so it turns out this big massive computer function can be decomposed into smaller functions intent model and view where intent translates the user's interactions the model does the heavy lifting and the view translated it back to cat pictures and if you're not satisfied with this with this decomposition you can split it into two functions or you can split it into six functions I don't care so these are just functions and as a good programmer you should know when to split a function whenever it gets too big right well this is roughly what my framework called cycle.js does you can find that in it in that address up there and the event stream that it uses uh come from this Library called rxjs a reactive library now what psycho JS does is basically solve some problems with this code what we wrote some minutes ago first of all this is boilerplate why we don't want to write that in every app and this is mutation and it's also boilerplate we don't want want to write that every time in our code and then we have two event streams to represent the same thing one of them is the proxy and the other one is the real when we attach them to each other so all all of this mess you just want to care about this part right you want to specify as a programmer how does the computer work in this user interface so that's what psycho allows you to do is just specify one function and it does the rest of the loop for you and this is the API basically two functions actually for this presentation we just need apply to Dom where we give there the computer function and we say where in the Dom will this live so the container there let's see how we can use this so imagine a hello basic hello world program where there's this one big input field where you insert the name and the um header just greets the name let's try to code this quickly so we can call apply to Dom giving ID app as a poter to where on the Dom should our app live and the computer function as the second parameter if you call interactions. getet you it will return you an event Stream So you give do field as a selector and input as the vent type so this will this will return us the event stream of input events on the field element so we don't have that yet but you're going to see it soon and I call this change name dollar sign and dollar sign is just a convention to say that this is an event stream you don't really need it so name stream will represent the actual data that we will display so it needs to have an an initial value so we just choose empty string otherwise it just takes everything that comes from change name stream and then we convert name stream into screen stream by Mapp in every name to a div that displays this data so notice now that we have this uh input element with class name field and now it makes sense how this will work because with the first line there it's after all a cycle right and then we just return uh at the bottom screen stream we can also rearrange this code by doing something which is not magical don't be scared and we get this so just rearranging so literally what the key what the computer does is translate from keyboard to screen you can clearly see that in this function it gets uh interactions events from the keyboard and it generates the screen so remember that of course we can refactor this computer function to smaller functions composition of intent model and view so how would it look like if we would split it like this well first of all the intent would take care of interpreting whatever the user is trying to do and this function just wraps those two parts that we're doing so whenever we get an event of input on that field we just get what is the value inside that element and then the model takes care of um of taking whatever happens on change name stream from the intent and just make sure that it starts with some initial data then the view converts the model's name stream into these divs and finally the computer is just sub function composition of these three so you choose you can either do it like this or you can do it like that or like this it's up to you as the programmer so what have we just made here model view user and intent are functions and between each of them is an event Stream So name stream is the output of the model and the input of the view and Screen stream is the output of The View the input and of the user and so forth and guess what you know this is unidirectional data flow and this thing here was functional programming and immutable techniques and these food sticks were you know reactive programming that's another name you can give to reactive programming other than reactive programming food sticks yeah and the divs that the view creates they are using the virtual Dawn so it turns out that not all of these Concepts were that scary after all right I mean we saw that most of most of these actually just emerged naturally from those in insights that we got from user interfaces oh and hey one last thing remember the human computer interaction what happens if we replace the computer with another human I mean if the computer has senses and expression can't we just replace the computer with anything that has senses and expression so what if this model here can actually represent any kind of interaction whether it's computer and a human or it's a human and a human or it's a computer and a computer Etc so in in an interaction with another human you take um input words with your ears and you output words with your mouth right so when Alice hears friend Bob saying what's up she processes that in her brain and she outputs her answer the event stream of Alice's words is her part in the interaction and then when Bob takes Alice's words as input he also makes an answer so it turns out that Alice's words are an event stream as a fixed point of the composition of Alice brain with Bob's brain so if we merge uh Alice's words with Bob's words we get an event streams of words from both of them which is what you know we normal humans name as just a conversation thank [Applause] [Music] you let's have a sit on this awesome awesome seat so so from what I've noticed there were no questions on Twitter okay I'm a little bit disappointed but um we have someone with a mic so if there are any questions from the audience anyone can't see anyone seriously any oh there's a question over there awesome okay thank you for your interesting presentation and um you wrote some uh markup in the JavaScript uh does this framework or something use react or something different yeah um is this mic still yeah um yes it actually doesn't use react it uses virtual Dom um virtual-on that's the name of the library uh basically because I want to get the different patch um algorithms and and I want to use them in the framework so react doesn't provide that um but on the other hand uh the community around cycle J just made this cycle Dash react which where you can use uh react there and also the the markup you can use jsx with psycho but normally I use this virtual hyperscript is just an age function but you could use jsx as well thank you any more questions yay hi uh last time I saw s GitHub page is under development is uh this yet or production ready now um yeah so this is not production ready because actually I'm redesigning it quite a lot like so the first version I made was had a completely different API than this and if you would build a production API production app on that it would have you know been like angular 2 but instead of that effect it would be angular three four five six and seven so because this is really new stuff and sometimes you just really get it that okay this is like I need to remake this because I actually discovered that I need to do this better um but finally now I think we're converging to a very nice API I don't I don't think I can get nicer than this so soon enough I think maybe you know a couple of I can't promise anything but you know yeah thank thank you thank you uh we still have some time so maybe another question there it is see you won't ask questions why won't you ask questions on Twitter no internet that's true yeah hello thank you for your presentation uh how to handle errors in this reactive pattern should I put errors on the same in screen stream or for example on that conversation between Alys the errors should go to the same stream or some um uh individual stream yeah so rxjs this library for event streams it has these uh error handling operators already for yourself and when you watch uh Matt's presentation about RX he's going to explain it completely you're going to see that yes you can handle arrows here so it's really not a a mystery but I I'll leave the all the details to to him because you're going to see in the presentation quite nice but yeah you can handle arrow and it's it's just not a problem thanks okay one more so many questions then uhhuh hi so if you're thinking about these small little apps that you showed they are easy to comprehend in Cycles but what if you have like a web store or something like that would you want to do SE several of these little Cycles or would you want to uh make a really large app that somehow just merges all the different Cycles together yeah so um when I showed the API there were these two functions one of them was applied to Dom and the other one was register custom element and the other one the second one we didn't use uh and that basically creates kind of components of of you know react style so you can build uh components with cycle and the components are also uh specified just like the the computer function was so it's also so you could think of the components as Cycles also so they're kind of mini programs so yeah and so basically the tools for build building very large apps are components uh react style and also just you know decomposing your function into smaller bits and yeah okay cool thanks Bobby good awesome um we have another speaker yeah um one more round of applause [Applause] please
- from
- Must Watch Talks, Cycle.js
- added
- 2026-10-10
- likes
- 0
Must Watch Talks › 2015: “[32:19]”
Cycle.js › Learn > Videos: “Presentation at JSConf BP2015 by Andre Staltz”