 Okay, so I want to start with two announcements. So PA8, the jQuery project, has been assigned. This is the project where you take the browser that you finish, which does put all the pieces of what you built so far together. Parses an HTML file, builds a tree, does a tree traversal to compute the layout and renders it. Now you'll add scripting to it, including a baby JavaScript. Sorry, jQuery implementation. So you should now be able to easily traverse the tree and actually modify the style of the document pretty much the way you do in jQuery. And you see how jQuery roughly is implemented. We have simplified the design for you so that it can be done more quickly. A few other things I haven't yet posted instructions on how to submit the design document for a final project. Essentially, this is the stage where you should have you fleshed out the design of your language and have examples of what you want to implement, sort of in the spirit of the handout that they give you for the weekly projects. So the design document should be something that you take once the class project and the final is over and implement your design. So at that stage, it should be about a week of work comparable to a PA. So I'll post that tonight. It should be due sometimes at the end of this week, early next week. But I hope you have been thinking about it since that design document is not something that you can just write down a day before it's due. It requires a few iterations of short meetings with your partner. In the lecture, I want to start today. Yes, I cannot hear you. Sometimes early next week, I need to look at other scheduling constraints, but perhaps think Monday for now. So it should be essentially fixing the constructs of the language. You should write down the examples that you want to implement and support. And of course, there will be changes to the semantics, changes to the examples, but it should be a document from which you start implementing. So it should be as close as possible to the handout that they give you. You should have the steps that you go through. Of course, you will need to revise it since you have not implemented before. But it should be as best as you can given that you don't have the prior experience. So I want to start the lecture by refreshing the JS arrow or the arrowlets topic that we talked about, which is a library or a DSL to make asynchronous programming with events a little bit easier. And I'm using the slides of the guys who actually design and build this because they have some nice examples. We'll go through those, and then we look at the implementation, which we covered only partially last time. So this is what we know already that JavaScript is the fact of the assembly language of the web. It is assembly because it is widespread, and it's assembly because many other higher languages either compile to it or are implemented on top of it. It is becoming more and more rare that you write your code in plain JavaScript. But what is the JavaScript programming model? The programming model is that you have elements in the DOM. You can register on the elements event listeners, which are handlers. Here is the name of the event, and here is the actual handler. So this function will pop up a window with the message clicked when you click on the element, some element in the document tree. You can also use this event model, which is an event comes, handler is executed to completion, and then you wait for the next event. You can use that event model to break long-running computations into smaller chunks. Because if you have a long-running computation in the browser, such as scrolling a document slowly over a period of, say, five seconds, you cannot have a loop where you just wait and spin and move the document because nothing else could happen in the meantime, such as moving the mouse and reacting to clicks on other GUI elements. So such long-running computations are also broken down into handlers. So here is a function that does some work here, and then it sets timeout to zero and calls itself. It's sort of recursive, tail recursive function. And this is what you do here in every iteration of that long-running computation. What's important to remember is the programming model, which is an event comes, handler is involved to completion without being interleaved with other handlers. It's single threading. And then you wait for the next event. That constraint we'll run into later today. So often things like drag and drop require building essentially estate machines because you're interested in a sequence of events to implement some interaction with the user. So here you wait for a mouse down, then you invoke a handler start, which does the work at the start, and you wait for a mouse up, and you do some sort of a stop. And here is how the code looks like for such a program. Here you have the handler that waits for the event. This is the mouse down event clicked on some dome element. Then you remove the handler because you have already executed this part and you clean up after yourself. So you deregister the start handler on this event from the target. So a is the name of the element on which you are clicking. You add the next transition. So you're now waiting for the mouse up and you do the actual work, the yellow. And then the stops does something. Corresponding to that. So what do you see here? That the control flow is not as clear as if then else or while structured constructs that we are used to from functional or imperative programming. The control flow is sort of hooked up by placing labels and registering the transitions. Well, so it could be that in this particular case it's fine. We talked about it last time that perhaps it is just defensive programming, which means you would really like to be sure that when the program finishes, you know what is the state of handlers. What events are registered on what handlers? Because if you sort of leave the handlers registered after yourself, at the end you may be surprised what the invariants are. So it's partly that. Partly it could be that you have other things that could generate those events, perhaps to simulate the user and the mouse. And so maybe two mouse downs could happen simultaneously. But it does make things easier in case you need to abort the computation in the middle because you perhaps decide not to finish the drag and drop. Then you don't want to go back to all these states and clean up after themselves. So it's perhaps nice to do it right away. But the key point is that the control flow is not obvious. And so there is a lot of plumbing. The plumbing here corresponds to the control flow. It's not really plumbing. It's important for the functionality. And it's interleaved with the action. And a good programming style supported by modern languages to separate these two aspects from each other and hook them up in a minimal way. So imagine now you want to grow the functionality a little bit. And you do something different on mouse up and something different on mouse move. So in drag and drop on mouse up, you stop. If you move the click up before you actually move, drag and drop doesn't happen if you actually move. You move the element a little bit. You nudge it. Now the program grows. And you cannot see even though in the visual programming style, there is a single place where we were able to attach this part of the state machine, which is really nice because we did the composition by attaching here a single edge. This is not quite the case in the JavaScript version of the program because this composition now had to happen here and here and here. And so that composition now has multiple points rather than one point. And so it's easier to debug and harder to maintain the code in general. So what do you would like? You would like the code that is as easy to compose as this. Think of it as cotton pasting this part of the code and attaching the edge. That's currently not something we have here in the source code. So now imagine you do some modification and you want two versions of the code. Perhaps depending on which browser you're running and you may want to run this or that. Could you just wrap it up in a function which is what you would normally do in functional programming and then somehow parameterize it with a parameter? No, you cannot. You need to essentially cut and paste the code while essentially literally. But you need to do certain renaming in order to make these two pieces of code independent from each other. So what did we have to rename? Why did we do it? What was the purpose of the renaming on the left? So exactly what we have here is that if by clicking on the element A, whatever that is, or when we lift actually the mouse on this element, we make a transition on that event to stop, which is this function handler here. Now, if we copy this code, presumably being in this state, we want to make a transition on this mouseup event not here, but instead we want to make a transition to this piece of code, which logically belongs to this. So we need to create a new version of names of all these handlers. That's why we renamed start to start one, stop to stop one. That would be fine, but also references from when these handlers are registered need to be analogously renamed. So even though in sort of the usual imperative programming we are used to the fact that you can just take a piece of code, copy it somewhere else, and it will work because the scoping of variables will protect the new variables, right? You cannot quite do that with handlers. So the ability to cut and paste disappears. And so it's harder to reuse code. And here is an example why that's so, okay? So imagine we want to make it possible to reuse the code. Well, what could we do? Can somebody suggest a technique that we used earlier in this class? So again, what we want, we have this piece of code which does listen on one event, does some work, listen on another event, does some other work. And now we want to make a copy and slightly parametrize, perhaps change the colors that the elements, the clicked elements receive. And we would like to do it without copying the entire code and renaming. Any suggestions what we could do? We could wrap it in a lambda, so we could do that. What we would achieve, presumably, that we have now an outer function, a closure, which has parameter x. And now this x does not refer the receiver here. The element doesn't refer to a fixed element A, but it is parametrizable. And once we have done that, we can call foo with A and foo with B. And now we can essentially say, now the element A and the element B, two separate elements, will run the same state machine program, which means if you click on them, something happens. If you leave the mouse, something else happens. On both of them, the same program runs. So does this work? So what is the problem there? So what you are saying is that when this handler here, start, is executed, right? When we are inside this body of start, now we want to make a reference to stop and set it up as the handler for the mouseup event. So let's see, is stop going to be defined and therefore visible at this stage? Should be visible, right? Okay, so if we want the behavior different on element A and element B, right, then this is not going to give us the different behavior, right? Because both of them will receive yellow and white rather than a different, some other problems. So that stop and start and stop function, okay, would be attached to what? Well, I think you are close, okay? The key thing is you write that we want to create different functions for these different behaviors. We just now need to figure out what do we attach them to so that the behavior differs depending on which of these elements, A or B, we click. One of them could be representing a file on the screen, the other one, I don't know, a directory. And so you may want to have different colors. Can you speak up louder? There is this fan here. Uh-huh, okay. So you are proposing to pass into foo in addition to X some additional argument that would now define the behavior, right? It would parametrize the behavior. Uh, we could perhaps do that, right? So now depending on which of these we have done it, now start and stop would be defined in a particular closure with a particular behavior. So we would take X which is the element being clicked and rather than setting its properties, a background here, we would apply a function which sets its background. Would that work? Okay. So next we have to start and stop. Has it been called? Uh-huh, so this is called the proxy pattern where you take the target of the event, so object on which we clicked and actually wrap it in an object, right? The object will have that element as a field inside, but the wrapper will also contain method just like any objects and those methods will be the behavior methods. And so we would not be passing here these objects A and B but we would wrap them here in some proxies that would carry the behavior and that behavior would be invoked here on here. So that wrapping thing is the more common solution but we could perhaps pass the function into foo as well but it's sort of a better modularity if the object carries it with itself in its proxy. Well, yes, you could but probably you don't want to since in different phases of the program the behavior might be different. And so perhaps in the context of the state machine program you wanna set the behavior to be just right. Why we don't want to pass the functions inside foo? Well, because there might be 50 of those functions that define the behavior and you don't want to enumerate them all. You better define them in the proxy class and then just create an instance of the class and pass it that way. So otherwise this would work, you think. When we make a reference to stop it is going to be this function. We agree that it's visible. What is X going to be? Is X going to be the object we want it to be? Is the closure business going to work correctly for us? It is not going to be a different object because stop is defined at the time Essentially you could say we run the program here foo on A. Of course the program is waiting for those events but we run it here on A and X will be the same everywhere and same for B. So that is working fine. So we agree that the target may need to be read but otherwise this seems to be working fine. So we talked about this. So arrow ledges the library which separates the control flow plumbing from the behavior and allows composition. So what do we do? How do we write those programs? The behavior we put into separate functions. The behavior is here. So the start here takes the target of the object and sets its background to yellow or background to white. This style here for simplicity doesn't use the proxies. The paper that you need to read does have that extra proxy layer. Here the slides don't. So that's all we need to do. So you may want to change for each state machine depending on what you are clicking on. And that essentially targets factors of the target which we set up after the state machine is all constructed. Now the state machine because the thing is composable we can build one by one piece by piece and then snap it together. So we'll first do this first half. And what it does? It creates an event which essentially sort of an event object which really does nothing just waits until that event happens on the target. So really does nothing until that event happens on the target. And after that happens it does the next thing and what is the next thing? It is the actual work that we call. So by composing the wait for the event with the start we are taking this arrow. These components here are called arrows because they can be combined with arrows essentially. And you can think of them this way. Here is the event arrow which just waits for something asynchronous, an event to happen. It receives a target, gets an event on the output. Okay, that's that. And here is the bind. Bind is a little bit special. If you look at the data flow diagram of that bind the result of the bind, what do you think it does? Why isn't bind some simple way of snapping things together? Why is that the bypass over there? So to help you decode the diagram, this diagram here describes what f dot bind g does. You can now think of it as f is, think of it as a function, g is a function. But these are the function that we can snap together into these data flow graphs which wait for something, do something, do something. So f and g are those pieces that we combine. And bind is an operator that combines them in a particular way and here is what bind does. Now, in this particular program here, what is f and what is g? Let's start with g. What would be the g in this composition? That should be an easy answer. That would be start, which is a function that you call to, in our case, just change the color of the background. What would be f? It would be even the entire thing here. So this entire thing, what you see, is going to be plugged in here for f. I apologize for the blue thing. So why is there a bypass over f? What are the arguments of g? So g has two arguments and that's part of the question. We want to sort of infer from the program what would be the arguments of g. So if you look at this diagram here and I told you that this is f, so f is plugged in here, what would be the argument to g? The input to f is one argument to g and the output from f is the other argument to g. So g receives the target as the top argument and the event, which is what happened on the target as the second argument. Why does start want to receive both event and the target? So let's stop here. So start needs to act on the target, say to change its color. So it needs access to the target and that's the reason for why bind is a special kind of combiner which doesn't just glue f and g together. It also takes the input to f and passes it to g so that g has access to that target. That's good. And why does g also need the event? Why would a handler need an event? That's not specific to this special arrow-style programming in any JavaScript program. You often read out some useful information from the event, seeing the coordinates, the time, what not, right? Exactly. So it needs both and the bind is a special combiner that snaps f and g together but also the source to f is passed to g. But sort of at some abstract level, you can just think of them as they are snapped together and look at the nice explanation they have. Essentially, you can read out the program as wait for mouse down on the input. We'll see soon how the input is combined into this. This program so far has not been attached to an input. You see, the a is still gray. And then you do then and then you call start on the target and the event, okay? So far, so good. So now, right, so arrows include the handlers, the regular functions here, and also asynchronous functions. So here it is the waiting for the mouse down event. Now you can, in a similar way, create the second half of the state machine with mouse up and stop, and then you combine the two halves together with next. So next is like bind except it doesn't bypass that information, that source. So there are two types of arrow, right? So those that invoke handlers on some target receive both event and the target. So target and the event. So think of it this way. So between here and here, what composition do we want between mouse down and start? We want to send the event that happened here, and we want to send the target. So two pieces of information flow here. Between start and mouse up, we do not want to send the target, because the target, sorry, we want to send the target but not the event. The event will come here, right? So the target flows here, event is attached here, so here we are sending target and event. Here we are sending target and event, and here we are sending only target. So where only target flow through, we are binding them with next. When the event also flow through, we are binding them with bind, okay? So this is the composition, it's just plain snapping together, and what is between F and G is the target. Now how do we attach the target? So now we have a program, step one and two, that's the composition of the entire thing here, and now we say run on A. Now we attach it to an element. You think of it as run, that when you run it will actually do some work, of course it does some work only when the events actually arrive. So it's sort of like in JavaScript, register handler nothing actually happens, it happens only when events arrive. Now you can compare the old style and the new style. So in the previous one, the control flow is spread out through the program, whereas here it is in one place, and you just parameterize it by giving it the element right there. So this is a sign of good refactoring, of a good programming model that you don't have, you can take its statements of the same information throughout the program, but you can state it in one place. And the composition is modular that you can reuse it. Okay, so here is the drag and draw example, and what those guys did is looked at four different libraries that implement drag and draw because web browsers don't support them natively. And they have sort of around 200, 400 lines of code, and they looked at where the plumbing happens, which is the registration of the handlers and where the actual transitions happen, and it's all spread out through the program in all of those cases, whereas in the example that they will show you next, which we looked at last time, that composition of the state machine or what happens next happens in one local place. Okay, so here is the drag and draw using arrowlets, and let's see how we would build such a state machine. What you see here is a state machine that you can actually build with paper and pencil. And we are going to now write it in this domain-specific language pretty much the way you see it on paper. So first of all, what it does, when you do mouse down, setup is called and perhaps you draw a star on the element. Now when you do mouse up, you drag it and you move it together with the mouse, and then as that repeats, you move it until you drop it at which points you are done. So let's build the state machine. So you now build the event arrow and you compose it with drag. So again, this is bind because here we flow the target and the element, target and the event. Now we want to do a loop. So let's see how they decided to implement a loop. So it's perhaps not as beautiful as in the picture, but not too bad either. At least it is nice and composable. And the state machine that is the loop can in itself be used in a bigger state machine so you can hierarchically build up arbitrarily complex state machines. So what do you think that does? So let's first try to understand this call here. So what do you think this call, the repeat call does? It acts on something. What would be the receiver of the repeat call? What data type would that be? It would be a state machine in this case, but in this language is it going to be a function or an arrow? Arrow are those things that we can bind together with next or bind. It would be one of those arrows. So repeat is something that doesn't compose with something else but places this loop back. It will execute the arrow again and again and again until when? Presumably we don't always want to have an infinite state machine. So what would be the trick to decide whether that loop should be taken again or not? So that's sort of the logical explanation. We want to do it until the mouse move doesn't fire. So as soon as we see mouse up event, we want to exit from the loop. But of course the language, the arrowlet language doesn't understand these events. That's what you want to achieve as a programmer. We somehow need to tell this loop that we want to exit. We need to have some way of breaking out of the loop or notifying that the loop should not iterate again. So that's exactly what happens. You can think now of the body as having three arrows composed together. Mouse move, an event, drag, a handler, and repeat. And the repeat does nothing but returns a special value. Who reads that value? Well, the repeat does, this call here. And if that value is the special value repeat, then this is just called again. And the program as written here would indeed iterate forever because the arrow inside the loop always returns that special value repeat. But of course if we now add the second half, now we have the second alternative which returns done. If this alternative is taken, then done will tell, is going to tell this repeat call, okay, don't call me again. It will exit the state machine. And now we just need to figure out how to combine the two. And again, there is a special kind of combiner which is called OR. It will take two arrows, whatever is here. Mouse move to repeat. And the other one mouse up to done. And it will snap them into one arrow that starts here and ends here. Essentially that's it. So now you can think of this F or G and starting two arrows that run in parallel concurrently is the more correct term. They are both in flight waiting for their events to happen. One of them is waiting for mouse move, the other one for mouse up. Are both going to happen? One of them going to happen depends. What do you think? Clearly there is a situation that none will happen, right? If you don't click on that event, it doesn't happen. Now it could be that one happens or the other happens, but could it be that both of them happen? So that's exactly what we want. And this is the special extra trick that they do in the implementation which is when one of them happens, you shut down the other one, which means you need to unregister the handlers for that event because it is an arrow that was in flight, meaning waiting for its event and you just shut it down. So you sort of unregister it and cancel it. They even have support for sort of listening to the fact that it has been canceled. So now what we have done through this composition, we have built another arrow that from the outside looks like an arrow. Now we have achieved composition like you are used to from functional programming. You from smaller function build a bigger function and on the outside nobody knows whether there is just one statement inside or zero or a bunch of function, whether the function is recursive, it just looks like an arrow and it's ready to close with other stuff. Why is this edge here? Well, you're saying that this arrow here should perhaps be going from a repeat. Yeah. Okay, I see. I think if you understand what you are saying, saying that this edge here, the back edge, should go from repeat to here and then should go directly to the exit. I think that would be better visual notation, I agree. I think what they wanted to show here is the composition that you took the drag arrow and the drop arrow and you combine them with or and you get a bigger arrow and then you combine it with repeat into yet bigger one. So essentially say that all these arrows are sort of single entry and single exit. But yes, if you look at the control flow rather than the sort of hierarchical composition, then it is true that the repeat always goes back. I think they wanted to show you here that now they have operators for combining arrows pretty much we are used to from programming with if statements, while loops, which all have single entry, single exit. I think that was the motivation. But I see why it might be confusing. Yeah, I think that this is another way of saying what they just said that you took the then sort of the drag part and the drop part and both of them will come to this point and then depending on which value was return, you make that back loop or not. I think you can think of this joint here being a separate kind of node where the thinking actually happens that corresponds to this repeat operator. Yeah, I think the visual language could be a little bit tuned. But the important thing is the text which is easy to transcribe into some visual thing and it is sort of self-explanatory. So now we can combine it with another mouse down and set up call here. Bind is used to set up with event A and next we just attach the green stuff to this. Then we have a bigger state machine and now you attach it to a target. If you wanted to do it for all elements of a particular kind, you would just do it repeatedly. Okay, well, why is this a good question? Is this first part? See that these parentheses go from here to here. Why did they do it? And is it redundant in the sense that removing them would give us the same behavior? Excellent question. So what do we... why did they do it? It might be for clarity, it might be actually semantically important. So let's just try to see why for clarity they may have done it. Mm-hmm. So it is for clarity exactly. Essentially what you are saying, let's construct an arrow from these two components and it is here in these parentheses, hence the parentheses, they could also use a variable to have a reference to that arrow and then use something like startupstuff.nextdragordrop, but they did it this way. So that's for clarity exactly, but, well, would... Okay, so let's see, if we parenthesize it differently. The other alternative you are saying would be... Just not parenthesize it exactly. Right, excellent point. So if you drop these parentheses, remember these dot things are still just plain JavaScript function calls. They return these special objects which are arrows they are composable, but the dot bind call is just a call. And so the usual precedence of JavaScript applies. So doing... If we remove these parentheses, it is still the case that this is evaluated first and then on the result you evaluate dot next. There is no precedence issue. Okay, which is to say you remove parentheses and it's evaluated in the same order. Exactly, exactly. In fact, there is no special grammar here because we are just relying on the JavaScript grammar. But we'll get to this issue hopefully later today and we'll see that the question of parenthesization does come up when we are composing bigger graphs. All right, so this is something we touched on that if in the previous style you are waiting for two events, so remember what happened in our programs. If it happened that this event triggered and the other one didn't, we had to, in this handler for mouse up, clean up the register, the handler for the one for the event that did not happen, and vice versa. So now these two branches that could alternatively happen were referring to each other. Their code would do clean up. Remember that, how essentially for the handler for this we would deregister this and vice versa. Here nothing like that happens because the OR operator has the logic inside. Not easy but general in the sense that no matter what arrows you put together, it will clean up the other stuff if the other branch was not taken. It essentially keeps a queue of events to deregister if you are triggered. So you get that clean up for free as you would expect from such operators. So now this, let's see what this is. This is a different version. So now I can see I didn't make this slide because this one I don't remember. Perhaps it says what we wanted to say. So we looked at these examples before and they show how you could actually reuse the same state machine for building other games. Imagine a jigsaw puzzle where you are moving an element and when you drop it you realize that you cannot drop it. It forces you back to the state where you are again moving the element until you drop it into a legal position. So here is an example of how that can be set up. So now for the implementation. I want to switch to the slides here and focus on how this language actually is implemented. So here are some of the operators that we looked at. We looked at repeat bind and next, not the product but we looked at or and here is their semantics. So now we want to build the implementation of the language which is what is inside these functions. These combinators essentially are the operators of the language. The arrows are the data types that are being combined. So they call the language arrowlet because there is a special data type essentially popularized by the Haskell language called arrows which allows you to compose things together by separating the composition and the behavior, the actual computation from the composition. So these are the two things, the control and the logic that we want to pull apart. So they use them to design this language. And this defines what an arrow is. An arrow is nothing but an instance of a class that has two functions. You could say A is sort of a lifting function. If F is the work that you actually want to do, say change the color of the background of an element. So if this is the work that you actually want to do, say changing the color of the background, then calling A of F is going to lift that work into an arrow. And by lifting we mean that now it is composable into that pipeline. So you're turning that function which does the work into some object that is now composable with others. And the composition happens with the next operator. So you have two arrows, A1, A2, you compose them into a bigger one. The real language has, as we've seen, multiple such composition operators. There's the next, it has the version of bind which bypasses the operators. But these are relatively subtle differences. So these are the two things that you need to have to be an arrow. Lift the work up to a composable element and then give you operator next for composition. It cannot really be simpler than that. You could also think of this if you don't like the idea of lifting a function to something that will be executed in a pipeline again and again. You can think of it as you are creating an arrow which inside does the work F, the function F. So we'll go through it in four steps. I think we'll only cover three because the fourth one really just does the cancelling, which I don't think we can cover today. We'll first show how we implement arrows for just plain function composition. Then how we do it in this continuation passing style and then how from that is just a convenient step to simple asynchronous arrows. So function arrows in JavaScript. So who knows JavaScript enough to translate this to Lua 164 or Java? What does this piece of code do? I'm really asking at this stage about that. Let me paraphrase it into something easy to express in a few words. So let's leave that on the background for a second. We are talking already about lifting a function. What I was looking for is if I look at this piece of code and I don't know anything about arrows and I want to translate it from JavaScript to some language like Java. Is this defining a new class? Is this creating a method? Yes, to what class is it being added? It would be nice to decode these JavaScript paradigms for those who don't know into something more familiar. So what does this do? Exactly. So what it does, it's adding a method capital A to all functions. Functions are objects in JavaScript. They belong to class... We know it's a prototype, but we can abuse the notation. So you can think of function as being a class. And now we are adding into that class a method capital A. So all functions now will have that method A. So does it mean that I could now do something like function f and empty function? Can I now do this? Exactly. Because this here is nothing but... It's a function, but it's also an object of this capital function class. It now has this method A and I'm just calling it here. So let's say this is adding method A to... I'll use double quotes function. Now what does that do actually in terms of the arrows lifting semantics? What will this keyword refer to? When the function is called it will have some value. What is it going to be bound to? So here I did... Essentially I wrote lambda. I'll simplify it. So when I make this call, what is this going to be bound to? It will bound to this instant, this particular function here. Excellent. So essentially what we are saying is that to lift a function into an arrow in this particular style of arrow, this will all change as we go to the next more realistic implementations, you just return yourself. In other words, in the way we represent arrows here, the function is a regular function. It is also a representation of the arrow. In other words, we don't need to do anything special with the function to make it composable. So lifting it into composable state, we have to do nothing. All right? Now I'm afraid I'll have to... Okay, let me not erase it. I think I'll do this good enough. All right, so now we are adding method next again to all functions. Okay? And I'll see what we do. We know what this is. This is going to be a receiver, right? So if I do some function one, next some function two, now this is going to be f. Now the other one is going to be g. Okay? Now why do we do that? I read about it last time. In case g is not a function but say an integer, we may be able to define this a call for integers to lift them into composable things. We will need to turn them into functions to be composable. And now here we create a composition. So here we actually compose. And we do it in the simplest way, call f and pass the result into g. So there is nothing special here except to act as a contrast when we look at the next implementation of arrows. So we'll do this. So now I obtained add two. What does add two look like? It's a function with how many arguments? Zero, one, two, one, okay. So can we call it? We used to do something special with these arrows. We didn't just call them. We had this dot run thing that would actually call them. We haven't defined dot run here. Why not? Because for pedagogical purposes we are lazy but we probably really should. Since this kind of arrow is also a function, we can just call it like that. And it will return three. It will call this composition here. Okay? Yes. Probably to be really kosher, you should do, yes. Well, if we wanted to be proper, we would call, let's see, this dot a. And I even put the parentheses here just to make sure we know what we are doing. And even here, we should really define a dot run. Because if this was a strictly typed language like Java, nobody would allow us to sort of overload it so easily between, well, is this a function or is this really an arrow? But here we can. So that's right. Properly you should do it that way. So good understanding. Okay? So nothing special, but we have defined a that takes function into composable thing and then next which composes them together. This is not particularly useful here, of course. But this is a stepping stone. All right. So what we have seen is a direct style composition, meaning you want to compose g with f? Well, call f. And in the meantime, g is waiting for f to finish. It has an entry on the stack. Okay? That will not work really well for asynchronous programming. Why not? Well, imagine that this is your event handler. Imagine that f is a function that wants to block and wait for another event to happen. So imagine that this handler here is a handler for, well, let's see, mouse down. And imagine, okay, let me, let's say, let's make this mouse up and I'll make this mouse down. Okay? So you are in the handler for mouse down. That's the function here called handler. And now you call f and f decides to wait for mouse up. In the JavaScript asynchronous model, you cannot just say, hey, sleep here and wake me up and continue from this point when this event happens. You could perhaps do it in other like p-threads or other moments where you could sort of say, wait here and some event will wake me up and continue. So again, JavaScript handlers need to finish to completion. Then you return to the main scheduler and another handler is called when another event comes. So if f decides to sleep, it just cannot. Well, it can. It can just return somehow. But then after the event happens, it cannot return back inside f and continue and then pass its control back to g. So we have a situation where we have sort of C++ programming where we would just like to wait, suspend our thread and wait for an event and continue, but we cannot do that in JavaScript. It's a single thread. Events need to finish. How do we finesse the composition of f and g? So that when we wait for an event, we are always at the end of the handler. So when we are composing the plain function arrows like the one that changed the background of an element, we can compose them in the easy way, the usual direct function composition way because they execute synchronously one after another. But when you are composing these arrows that wait for events, those event A arrows, you cannot compose them in that style because when the handler for this one finishes, you need to be able to return from the handler and when the event happens, then you transition to the next event A arrow. Somehow, when the transition from this arrow happens, you need to be at the end of the handler so that you can return from it back to the schedule. So if I understand correctly, somehow you're saying that g needs to be called only when that event happens. When that event happens, we jump to the beginning of g. So we must not write it... Well, I think we will be able to do it without the abuse. Let's see what the other proposals are. So we had the special trick which we called continuation. So the function f would do what? It would not return, but the next... You could think of it as a program counter into which it needs to go when it is ready to relinquish its control and pass the value down. This will achieve two effects. One of them is that the transition from f to g happens exactly when the f is at the end and done and it computed its value. And when we transition to g, we'll jump to the beginning of g. Right now we are in a situation that g is sort of in the middle. Executed this code of the handler. Now g is waiting for the argument to evaluate. It's on the stack. It's pending its execution. You implemented the interpreter so you know how it looks like on the stack. So if we do it in the continuation style, f is done and we jump to the beginning of g. So let's see how that looks like. So this is the continuation passing style because you pass into the function a continuation of the execution. The continuation never returns. It always continues. So a function now takes the normal argument x. It could have, of course, more than one argument. And also a continuation, which, of course, is also a function, but you can think of it as this is where we jump, where we continue. The continuation actually will receive what? k has one argument. What do you think is that argument for that continuation? It would be the usual return value where f will be passed there. And so, effectively, whatever f would normally return would now be passed to k, and k will do the crunching from it. It may seem strange that the entire rest of the computation, which is represented by k, can be described by a single value which you pass from f to k that doesn't seem plausible. Are we saying that f finished? k is the entire rest of the program, and it's enough to give k a single value, the result of f, and that describes what the rest of the program should do that doesn't make sense, right? So there must be something else hidden somewhere. Well, I would say that's an orthogonal question. When k finishes, the last continuation is simple. The last continuation you call is sort of an empty body function. And you could say that... No, but eventually there is a last continuation. The rest of the computations are composed from smaller continuations. Well, it has the value, return value from f, so it has something. What about the rest of the variables? Where are they? Well, you sort of pass them, but it's simpler than that. Where are the rest of the arguments? Well, k is a closure. So when you create k, the rest of the computation, it has access to all the variables in the environment. You're familiar with the closures. So it receives the return value from f and all the other variables that it needs to have access to are available through the environment because k is a closure. And you may be surprised that how could these closures just... Sorry, continuations call each other. Wouldn't they just blow up the stack? But since you never return, you never return, you always call another function, you do tail recursion optimization. When you call closure, you can reuse your own call frame, so the stack doesn't grow. So you can really think of it as a jump rather than as a call. The stack doesn't grow. So truly, continuation is just a jump, except it has this nice property that the return value is passed as an argument. The rest is available through the environment of k because k is a closure. That's it. So this may seem pretty advanced, but this is how people build these libraries today, and that's one thing you want to understand in this class. So here is a small example of CPS. So in this direct style, imagine we want to print the value of G of 1 plus 2, and here is the plain direct style definition of G. And here is how you would rewrite it into continuation passing style. So now you see G receives a continuation. We do the usual work of G, and now the value is passed into k. And what is k? Well, what did the path do? Well, what did the pass as the continuation? Well, we take the value, add 2 to it, so we take the work from here, and we do the actual print here. You see that it's not quite fully continuation passing style. Where did I cheat to keep it simple? So I'm sure you understand what we are doing, right? The return value of G is passed into k. What does k do? It's this function incremented by 2. So this is the return value. It's the result of X divided by 2, and then we print it. So what else maybe I should have done? What is it that you don't like about this? Why do you feel it's maybe not full CPS? Okay, let's try it. Okay? So indeed I didn't do the nesting quite right. What should I have done different with nesting? Okay, so see there should be perhaps another there is some work here. The result should go into another continuation k. What would that continuation contain actually? The print, right? And the continuation that does the print perhaps should also take the result of print and pass it somewhere. Where would it end? Well, eventually some of the continuations would be an empty function. There is actually one step of the continuation style here to make it easier to see. You look at more detail once tomorrow in the section. Okay, so let's now so what are we going to do? We have previously built arrows for plane functions. It was truly just a toy just to show you what the interface is a and next a to lift next to glue together. Now let's do it in the CPS style. It is the same on the outside because we are still taking functions lifting composing but the implementation inside will be in the CPS style. It will now look hairy. It will look like we are scratching ourselves this way but it will then make the transition to events trivial. So again I'll ask for a translation from this JavaScript paradigm to something familiar to us like Java. So what do you think is going on here? Not in terms of lifting and gluing but in terms of JavaScript. Are we defining function? Well, yes, obviously. But are we doing potentially something else also? I'm not sure I follow that. Can you try again? So this CPS, I can tell you what this is going to be. The CPS is going to store or keep maintain the function itself. Sort of the function, the body, the actual work. We just call it CPS to remember that this is a function in CPS style which means it has this extra argument. And you even have this type here. It's a function that takes one argument, the normal x, the continuation and returns what returns nothing. So yes, CPS will store that but again what is this piece of JavaScript code doing if you had to rewrite it in Java? Would you translate it into a method? Okay, so this is a function that creates an instance variable. Is this a constructor? Well, there is something analogous here, right? So let's go further and come back to it here. Okay, so okay, so what are we doing here? Can we now say if this was a Java program what would this slide do? So we see certain patterns here, right? What does this do in JavaScript? So we see this twice. Is this... We see these CPS do they refer to the same object in the language? We have CPS four times. One thing this class should help you understand is these name spaces, right? Just the fact that you see the same identifier twice doesn't mean it refers to the same object. So which of these CPS identifiers are the same? Okay, exactly. Alright, so these are the same. And these are just fields, right? In the JavaScript prototype. So are we defining a class? Essentially. Yes, okay. So this is a definition class CPS A. Okay, and now it will have how many methods? Two, right? CPS A here and next. Okay, what about this function here? When is that called? The constructor? Okay, it is a constructor. So when you call new CPS A then this is going to be called, right? Actually need to give it an argument, right? In JavaScript here, it's sort of simple. You do new. New allocates a new object just a hash table. Then you call this function CPS A it's here. You bind this to this new object that you just created and now this entire assignment creates in this object the new field CPS and assigns to it this argument. It does return this as well, yes. But you don't need to do it explicitly since the new does actually do that. The new operator is responsible for returning the object which is in this function called to this, right? So once you sort of abstract away from how JavaScript does it, this is just defining a class CPS A with two methods and a constructor. That's it, okay? And now let's look at what we do here. Now we are taking next, right? So we are doing something like F a function changing it into CPS style. Next and function G and CPS A, okay? What will be F? F is going to be this thing, right? What is going to be G? This is going to be G. In case G is not CPS A, we are going to lift it if it is its identity function and now let's see how we compose them. This is the crux of the composition. So let's see, what happens here and what happens inside here? The new CPS A just creates another arrow object that can be glued together. We didn't have to do it in the simple functions because the function was also an arrow, so we didn't have to create a new function. Well, actually we did, right? We created a lambda with F of G inside. So sorry, we did create that. Here we create a new arrow here. What is now the function here for the arrow? Well, it is a function that takes F and calls the body with the usual argument. Then it passes it a continuation. What does the continuation do? It calls the body of G and then G will call the continuation passed into this composed function. So we are constructing a new arrow which receives X and a continuation. We do the work of F, we do the work of G and then after G is done we need to call the continuation. Which one? The one passed into this new composed arrow, so it's the one here, the one that passed into CPSA. That's this function here. It takes a little bit of thinking but once this is clear you are all done. And here is the definition of okay, here is how you run. See, and here you can see when you run you create a function so run is a function that does what? Calls the actual body, right? CPS is the actual work but it's a function in continuation style and here you pass it to the empty. So this is the continuation that is sort of trickled down and is called last. It doesn't call another continuation. This is where the execution stops. And what you see here to conclude is that look how we are lifting F in direct style. We are lifting it to CPS style. So again what is this? We are lifting a function CPSA to the function class. So now any function will have CPSA on itself. Meaning you can call a lambda with CPSA and it will turn it into a function in continuation style. And what it does it creates this arrow. We have this function in direct style here. How do we turn it into a continuation style? We create a function here which takes an argument and K. This is CPS style. We call F inside and then the result we we pass into K. This is the translation from direct. I don't think it had previous state. Some of them those that do the bind here we are assuming that they have only one argument. Yes, but if you did two then you need to create here an additional argument. This is an example of you could compose them and this is what I leave to Sean to walk over in the section tomorrow. By the way the entire language is beautifully presented on the web. There are live demos. You can edit the code and run it yourself. So it's all live, well documented beautiful piece of work. So much for today. Thank you.