17116 >> Ben Livshits: Let's get started. Thank you very much for coming today. It's my great pleasure to introduce Shriram Krishnamurthi, who is visiting us from Brown University for the next couple of days. So the presentation today is about Flapjax, which is an event reactive model for programming interactive for each web applications. Let's welcome Shriram. >> Shriram Krishnamurthi: Thank you. It's good to be amongst old friends, new friends, all sorts of friends. I would like to start by making sure that -- I'm a little late, thanks to the Microsoft complex, as I discovered. They're putting the complex in the word "complex." So I want to make sure that my talk finishes on time even if I started a bit late. And I wanted to be sure to write a program to make sure that happens. We'll write a Java script application to do this. I'm sure many of you have programmed in Java script, but most of you, patience. But for those who haven't, this will be a quick introduction for how you program these sorts of things. The nice thing about Java script it talks to HTML. You've already got a web page and you can make that web page do things by adding a little bit of scripting to it. I'm going to write myself a little Div, you can think of as a place holder called current time where I'm going to put the time. I have a function that sets the time by going into the Div. You see it says get element by D current ID time. It's finding that spot on the web page and then into that spot on the web page it's inserting the current time. And I have to also tell the Java script that I want to run this. So on my body tag I say here's the thing that I want you to run, unload, which is set time. All that make perfect sense? Okay. So if I run this program, why would Ben be extremely unhappy? There's a small problem. >>: [inaudible]. >> Shriram Krishnamurthi: Yeah, there's a small problem here. This will tell me how much time I have left and how much time I have left will never decrease. So it's great for me as the speaker. Not so good for you as the audience. So, in fact, perhaps I want a slightly different program. So let's say I want this kind of look and feel. So it's going to tell me how much time has elapsed and maybe I have a reset button. Let's think about how to write that program. So it's a little more complicated because the amount of elapsed time is going to keep changing. It's going to count up from zero maybe or count down from some number. What does this program look like? I'm still going to give myself a placeholder other the screen. That says current time and there's a little blank hole over there that I want to fill in. I've got to set some variables. I need a timer ID. I want to keep track of how much time has elapsed. I have to start the timer. And I use a function called set interval. There's a few different ways you can do this in Java script that are roughly the same. I want to do it every second. Tracks how many seconds have elapsed. I have to say what I want to do every second, which in this case is I want to get the current time incremented by one and stick it in the web page. I need to start that timer. But remember there is a reset button, so I create myself a button on the screen. And I give it the ID reset. But it doesn't yet have any behavior. So I have to go write the function that gives it behavior. So everybody here has written a GUI program at some point in their lives. Probably many GUI programs. So this style of programming is extremely familiar to you. Just the syntax is a little different. Now we should make sure we understand what this program is doing, right? It's just counting up. And when I click reset, it starts from zero again. The purpose of this program is to fill that hole over there. Now, how do we make sure that it's doing this correctly? Well, it's completely obvious, right? The value for that point comes from that expression over there. The value of that expression comes from elapsed time, whose value is set on the line before it, which happens if I call to every second. Do I actually call to every second? Well, yes, I do over here. But that's inside some other function set interval and that function is actually inside start timer. So it all depends on where the start timer is being called, which thankfully it is over here. But, in fact, there's more stuff on the screen, right. There's elapsed time equals zero which may or may not have some impact. It's pretty obvious that's the initialization. But there's also another elapsed time that's equal to zero over here which of course is called by reset elapse, which is called by this function over here. So we spent 30 years getting rid of spaghetti code, and we've done it very successfully. The reason about what happens in that little spot over there I have to think about timers. I have to think about initialization. I have to think about overlap, interference, the structure of call-backs and, of course, everybody in this room has spotted the bug in this program, right? Good. Okay. So what's happening in these -- there is one, and you can ask me later on. So what's happening in these programs is that we have a world out there where sort of time keeps going downward. And we have a program but the program sort of isn't always running. At some point something happens in the world. An event loop invokes a call-back. That call-back runs for a little time and returns a value back to the world. And then after some point in time again there's another event. The program gets invoked and so on. But the program in some sense isn't running between these invocations. You have these separate threads of execution and it's the responsibility of the program to figure out how to get values from one thread of execution to the next. And all these event loops return void in Java script, and they return void because the event loop is not part of the program, right? The event loop is kind of neutral. It's agnostic to the program. It doesn't want to know anything about the program's computations or its values. It says I'm just letting you know something happened. Don't tell me anything in return. I don't want to know about it. So any communication here is the responsibility of the developer. But these are all void returning functions. So immediately you've lost any notion of composition, any notion of typeful programming has been completely eradicated. Furthermore, the only way avoid returning function can have any effect on the world is by having side effects, which is why even the simplest program has to have side effects in mutation. Eric Meyer is in the room, he would tell you what's a bad thing. >>: He just walked in. >> Shriram Krishnamurthi: Hi Eric. Good. So I want you to think that void is a four-letter word. It's a bad word because it means even the simplest possible program I can no longer reason about compositionally, functionally. I can no longer reason about algebraically. I have to think about state. And, of course, if you're in a concurrent world, state and concurrency don't exactly interact nicely. But I'm being forced into that structure by the API. Now you all know that I'm really like a scheme guy at heart. Some of you at least know that. You all know this is really just an advertisement for scheme. Right? I'm setting you up. How would I write the same program in PLT Scheme, for instance? Well, it's a lot prettier in my opinion. But, unfortunately, it's no better. Because all these things are call-backs. They all end in send and send is an imperative operation and the return type of all these things is void. Okay. That's scheme. It's like a 25-year-old language. Clearly ready to be put to seed. So maybe we should take a look at a nice modern language like, say, a Java. I can't fit any Java code on the screen. The screen isn't big enough. I don't even need to look at the code. I can just look at the API documentation. You look at the API documentation, and there's a long list of voids over there. Okay. So that's the structural problem with Java also. But maybe it's a scheme in Java and maybe we should go to like good French programming language, nice stateful programming language like OCAML. Those guys are clever; they don't call it void, they have a different four-letter word called unit instead. But that's no better. It's obvious all along Eric were here he would say you should be looking at Haskell. What does Haskell do? Haskell is really clever. Haskell doesn't even use four letters. Instead it uses two letters and two other characters. But it is four characters all the same. Even Haskell, which rants on and on about functional structural recursive algebraic programming with rich types, can't seem what to figure out what to do about basic stuff like GUI. And even simple GUI had API, Monad and pollutes your program back to square one. So what's happening in these programs is that there's something peculiar about the flow of control of interactive applications. The programs in some sense don't run. They wait for something to happen in the world. And some event, maybe it's a key stroke or maybe it's a stock tick or some event happens, that event comes through the model which then propagates out to all the devices which may in turn cause further flow of control to happen. But the important thing in all these cases the program is not in control. It's the world that's in charge. All the program is doing is essentially listening to the sounds of the universe, right? It's waiting for something to happen, waiting to be told to do something and reacting. And all these APIs that I've shown you, all these return types of void are simply a symptom of that problem. So it's worth it for us to think about whether instead of shoehorning our existing languages into these programming frameworks, maybe we should ask what are the principles of programming in this style in the first place, especially since more and more of our programs are of this form. So I want to think about language support for interactive applications. I've done a bunch of stuff over the past several years on synchronous web programming using continuations and various other things, where we sort of solved this problem there and we felt pretty good about ourselves until, of course, Ajax came along and ruined everything for us again. It just means we get to do more research. That's good. Okay. So let's think for a moment from first principles about what information we're getting from the world. Remember, the program is sitting waiting for the world to tell it things. The world says things like here's the current position of the mouse. Maybe the mouse moved. It might say here's some key strokes and here's of keys you received. And it might be things here's the user location of the cell phones as we are these days. Might be a sequence of Ajax responses coming back from a server. Might be mode keys, might be mouse clicks, might even be, as we've seen, what the current time is. Now, of course, I've employed a rhetorical device here over a range of these things in a particular way. And as you can see I talk about current things and a sequence of things. And it's useful to have the dichotomy, because current things always have a value. But the value may keep changing even as you're looking at it it might keep changing, the current time, for example. And sequences of things are discrete. The mouse is clicked once and the click takes infinitesimally small period of time. You sort of can't even ask when it happened. But it's discrete. There may be an infinite number of them. You don't know when the first one happens. You don't know if a first one happens, and you don't know when the next one will happen. These are really two very different kinds of beasts. You've already seen examples of these in the simple program I've shown you, because over here that is one of those continuous things, right? It's always changing. It's always got a value. That's one of those discrete things. You don't know if [inaudible] will be clicked, you don't know when it will be clicked. This is an idea I'm borrowing from functional reactive programming. And a lot of what I'm talking about is trying to build and sort of try to make practical this idea that's been floating around in the programming languages community in a sort of obscure space in the PL community. It's great work, but we're sort of trying to use it to build lots of real world applications. So these things are called for peculiar reasons, behaviors and event streams. So if you ever see B, capital B, right, this is my Hungarian coding notation, if you ever see a capital B it means one of these current things, think like a timer. If you ever see a capital E it means one of these potentially infinite sequence of events, make sense? Bs and Es. Good. >>: I guess I don't understand why they don't unify where the current one is just the first element of an infinite sequence, right? >> Shriram Krishnamurthi: So there are, in fact, almost duals of each other. Okay. And many -and an implementation will try to exploit that duality. They're not exact duals of each other because duplicative events matter. Whereas duplicates if I converted this into that this wouldn't have an initial value that has an initial value. Other than those algebraic differences they're almost duals of each other. Good. All right. So the important thing is, of course, these things already exist. Java script has them and OCAML has them and Java has them and C# has them. But the important thing is when it changes. So it is either the current value changes or a new event appears, the important thing is we want all dependencies to update automatically. That is, we want to keep things synchronized, keeping things consistent, the problem of the language rather than the problem of the programmer. I'm going to show you two languages where this happens. One language is something called father time. And I want you to think about it as a scheme that behaves funny. Here's father time. And it's running inside doctor scheme, which is a programming environment. And standard scheme expressions just kind of work. They look exactly like they do in scheme. You write a functional expression in scheme, and it has exactly the same value as it should in scheme. And, in fact, that's by definition. You can even ask for something like the current time and it comes back with a constant. The current seconds is some number. That's the current seconds. Of course, even as it appears on the screen it's already out of date. But that's your problem. If instead I ask for something called seconds in father time, I get something that's rather different. Okay. And this is honest to goodness value but it's a value whose value keeps changing. In fact, I can do things with seconds. Right? Or I could even do something like an expression like this. And as you can see, I can nest as far as I want to. It's the language's responsibility to keep the overall expression up to date, not the programmer's. So I'm writing what looks like a functional dependency, but the value keeps updating because it's the language's responsibility. So there are several important ideas in father time that I'm not really planning to talk about in this talk. One is the incremental read about print look, like scheme or XML actually works with these values. We have a systematic way of taking all our libraries, in particular GUI libraries, and converting them into these reactive interfaces. For example, we took a 100,000 line GUI library with 100 lines of code we get reactive face so you can program it functionally. We have lots of optimizations and a very nice implementation strategy that reuses existing call by value languages. So a bunch of papers and stuff on this. What I want to do is, instead of talk about these ideas, I want to tell you about a slightly different language called Flapjax which is essentially the same thing, though. It's Java script that behaves funny. So let's see that timer program we talked about at the beginning of the talk written in Flapjax. Here's what it looks like. So just like I have seconds in father time, I have something called now B, which is the current time. It's a B which means it's one of these things that always has a value. So graphically you can think of it as being something like this. Right? It's always got a value, but the value keeps changing. I can also, say, take some element in the web page, any dom element and turn it into an event stream. So give me -- take the reset dom element, take all of its clicks and turn it into an event stream. So graphically it looks like this. Nothing happens. Bing. Click happens. Nothing happens for a while, bing, another click happens. Now what I'm trying to do is I'm trying to get from here to over here. That's the answer that I'm trying to compute. Right? That's the elapsed time since the last reset. How do I get there? Well, I want to know what time each of those clicks happened at. That is, I want to take a snapshot of the value of now B whenever a click happens. Well, so I take the previous expression I and I say snapshot the value of now B. If I don't snapshot it remember it will always be kept up to date automatically. Right now halt the computation for this instant tell me what its value is and remember that value. So if your functional programmer, that's the kind of a map. I'm just mapping over this event stream. But I really want to turn it into this, right? I want to turn it into a behavior. I want to turn it into something that remembers its last value. Well, so starts with is an operation that says give me an initial value, which is some starting time. In this case maybe 12 is the starting time. And hold onto the value you asked whether this could be inter converted starts with exactly one of those inter-converters. Start says hold onto this value until it changes, then hold onto that value until it changes and hold onto that value until it changes and so on. Now, this final expression is just the difference between those two expressions. That's just algebra. And I can send this to some show time. So the point is show time can just be some arbitrary Java script function. It doesn't need to be any of this reactive stuff. It's just getting a value. Whenever it gets a value it gets pushed a new value. It just updates it on the screen. So every time now B changes, it pushes a value to all the dependent expressions which also update, which pushes a value to all of tis dependent expressions which also update. If one of those happens to be on the screen you're just going to see the change on the screen automatically. So snapshot takes the event stream and it tells you when to evaluate this argument. Click had no information other than the fact that the click occurred. >> Shriram Krishnamurthi: Exactly. >>: It was a key click with. >> Shriram Krishnamurthi: It actually does have a little more information. It does actually tell you which key got clicked. Whatever Java script is going to give you, whatever event object Java script is going to give you is actually available. But I'm choosing to ignore it. >>: Use it as a separate argument to snapshot. >> Shriram Krishnamurthi: I could use it as a separate argument snapshot, yes. >>: So there's some dissecuretization going on? >> Shriram Krishnamurthi: Yeah. >>: And it's not clear how you're doing it. Obviously it looks like you're creating a new value every second. But where is that captured, essentially? Is it every millisecond? >> Shriram Krishnamurthi: Oh, so that's the function -- so the evaluation model is completely push-driven. So if I -- so now B in this case happens to be defined over a millisecond timer. But it's whenever the time creates signal to change, that's my unit of dissecuretization. So I'm dependent on whatever dissecuretization is already in the system. >>: If you've got multiple things generating things with different uses, then ->> Shriram Krishnamurthi: Yes, good. So in fact there's an important property in the valuation model which I'm not going to talk about in this talk but I could explain later, which is something that we call glitch freedom, which says that you never see things that are inconsistent -- you never get a value that's not consistent with the expressions you have in your program. Okay. So in this case, for example, if you have two different timers, they actually come from the same timer, right? Essentially you have some timer that's pushing in two different directions and coming back together. You're guaranteed that the value you get there is in fact the functional value you get from these two different expressions. And that's an important semantic guarantee. It's one of the important parts of what we did in father time was to provide that semantic guarantee that you really get what your expressions say. And a naive implementation will not give you that. There's a bunch of things I could say there, but I'm not going to say that in this talk. So just to summarize this expression, this is the expression. I take now. I take this event stream. I convert it to a behavior, say what it starts with, and the thing I like about an expression like this is I've turned time, which is an input, well, that's fine, that's just an input. But you don't think normally of buttons as being inputs. You think of them as actors or actions. You don't think of them as values. But I've turned the button into a value. So this whole expression gives me a value for the button. And I can just think of it as a value I'm computing with. And I pass it to a function. So I'm back to writing expressions that look like functions of inputs. And independent of the fact that these happen to be highly reactive and changing and so on. Okay. So that's an important detail about the way, about the programming style that this language engenders. All right. So we built a bunch of applications with this. We've had several people built third-party applications. We built several working applications that people actually use, so if something goes wrong my reputation is at stake. Yes. >>: So maybe we get to this later but I didn't see how the event stream model solves the problem of the dependencies that you earlier related to in the first part of the talk. You had complex dependencies among different parts of the ->> Shriram Krishnamurthi: So this is the whole program. There's a little bit missing but this is essentially the whole program. So the dependency between the button and the value of the button is expressed in this expression. I'm trying to answer your question right here with this screen. So the point is I'm not -- there is a timer hidden underneath here. But I'm giving you a completely different way of writing that program. I'm not telling you how to massage that program a little bit. I'm giving you a totally different model for writing that program, which is to think of all the expressions as being pure expressions, writing functional compositions of those expressions. So where does that breakdown? You remember the first slide I showed you was just a really dumb problem in Java script that put the value on the screen. I said what's wrong with this. As you rightly point out it only presents a value once. Okay. So what I'm asking you to do is think in terms of the program running once, right, but if you now change some of the sub expressions to actually be things that run many times, it becomes the language's problem to rerun the program for you many times. That's the model I'm presenting here. Okay? >>: Sounds like a complex [inaudible]. >> Shriram Krishnamurthi: A lot of complexity gets buried in the language. So things like the optimizations and things so on do become relevant. Yes. >>: This thing -- so in some ways it's a familiar model in the sense that when you, when you have an Excel spreadsheet ->> Shriram Krishnamurthi: Absolutely. Absolutely. >>: Propagated. >> Shriram Krishnamurthi: Exactly. >>: I don't know if there's a way to update a cell every second. I'm sure there is. >> Shriram Krishnamurthi: There must be. Some DB thing that you can do that Excel rewriter then picks up on. But I'm also giving you sort of the higher benefits of higher order functional programming. But, yes, it's spreadsheets and as you'll see it's spreadsheets extended up to mashups and so forth. Yes? >>: You said iteration models are there in the push space, I don't know, go back to the same example. You cover another one. There's no need to compute anything on the list of things, you would rather go into [inaudible] in that case? >> Shriram Krishnamurthi: Yes. >>: Windows appears again that you want to ->> Shriram Krishnamurthi: There's a complex argument in both directions, you're right. Okay. So, yes, you could view it -- that's a reasonably perfect thing. Could you if you wanted to add another event over here that said am I visible. Visible to you would be another event that triggers computation you wouldn't be computing it if it weren't visible. >>: Express everything that's [inaudible] the push model. >> Shriram Krishnamurthi: The push model, the push model has the advantage that I don't have to pick a holding frequency. >>: [inaudible] >> Shriram Krishnamurthi: Yes, yes. So there's several applications. So your programmers, your researchers you might write programs, actually you guys do write programs, you have to write your own code so that's the nice thing about [inaudible] a lab. I want to give you a feel for what it's like to program in this language. I don't want to talk about the theory. I there's papers for that. I want to give you a feel for writing abstractions. So let's start with a simple abstraction that I've pulled out. I'm not going to show you the whole application. Just show you snippets. This is an example that shows up repeatedly in the systems we build. But since you haven't used our systems here's one that you have -- well, maybe not in this room, but you've heard of something called Google. It's a company in California. And they build this thing called Google mail. Wherever I see Google you should hear Windows Live or buzz or bing. Imagine bing mail. In your mail program that's web-based what you'd really like is an auto save buffer. As you keep typing here, periodically the content gets saved onto the server. So if your browser dies you don't lose your content. I want to build an extraction like this because it turns out auto save buffers are useful for everything. They're useful over here. They're useful in conference reviews. You don't want to lose those either. They're useful in job searches. They're useful in various wikis and so on. So let's build this auto save extraction. And, by the way, notice it also does things tells you when it was saved and so on. You might also have some styling that says, you know, print, do something to the background when it's in unsaved state, et cetera. So let's write this widget. So I want to create a widget. Want to put it in a library to reuse it in lots of applications. Let's call it mix save bucks. Obviously it needs to create some kind of text area I can type into. We'll call it doc. And maybe every 60 seconds it's going to set off some timer to go off and save this thing and it returns document. Perfectly sensible. There's one short coming with this, right? What if you say I want a different frequency. You don't want to save 60 seconds. Maybe you want to make that a parameter. So we'll make it a parameter of T. But is that the only reason why you might want to auto save? Because the timer elapsed? Are there other reasons you might want to auto save? >>: What if somebody takes a button that says save draft. >> Shriram Krishnamurthi: Save now. Bingo. So almost as if you were planted. Okay. So somebody clicks save now and you want to save then also, right. Maybe we should add a second parameter that takes the button into account as well. So there's our thing. It's either every T seconds or when button clicks. I'm actually using the English on purpose, because it's not entirely clear what I want this to be. There's other possibly definitions maybe when the button clicks or if T seconds elapsed since the button was clicked or maybe it's like when T seconds and button or it's after every key stroke or maybe I want to do something if nothing changes or maybe I don't want to do something if nothing changes. So clearly it's obvious that I need to add about four or five more parameters. And that's when you go and read your [inaudible] grams. And perla says if you have procedure with ten parameters you probably missed some. So how can we present a better abstraction? To me there's obviously an abstraction here. It's an event stream. You want to pass an event stream and say you save every time the event stream fires. And I can then pass in different kinds of event streams. I can pass in a timer that says fire every 60 seconds. I could pass on something that says every time the box is clicked, or I could merge those two streams, right, to say every time the box is clicked all the timers fire or more complex compositions. So this is where now having a Goodrich programming language, a little richer than Excel perhaps, a rich programming language and the ability to write commonaters and the ability to merge the event streams becomes really useful. Because I've now achieved something that's a very valuable separation in computer science. It's the separation between mechanism, which goes inside, and policy which comes from the outside. And all these are representations of policies. Yes. >>: So when you merge two streams. >> Shriram Krishnamurthi: Yes. >>: What are the elements that you get? It seems like there's a type issue. >> Shriram Krishnamurthi: Oh, yeah, there is. Oh, yeah. Yeah. It's Java script, man. Until about, I don't know, 12:25 tomorrow I won't have to worry about this question. So, yeah, there is -- and in this particular case, the question is: What do you actually need out of this event stream, if all you're treating it as a policy you don't actually care about the content of it at all. So that's why I can ignore that question here. In fact, so just to give you a quick preview of what I'm talking tomorrow about a type system for Java script, and we can type all of these programs. So here, for example, the types would be very simple, because they would say all I expect is that it's an event stream. And if the mechanism tried to inspect the values of the event stream obviously would be in trouble. So this particular one that's just an event stream. So I get this nice policy mechanism separation, and a useful way of thinking about how to structure this program. And in fact a useful way of thinking about how to structure all of these sorts of abstractions, which is use event streams to represent policies don't do too much in the mechanism itself. Now, of course what I've done is I've shown you how to fire events, but I haven't told you anything about how to save something on a server. Well, so in web programming it's standard to think about the server as being the place where persistence is done in reference monitoring, access control and so on, and you just send requests and get responses. Right? And you have primitives in Java script for doing this. So we have a primitive in Flapjax called get web service object E. Terribly unwieldy name. But I'll abbreviate it in the talk. But the important thing is get web service object E takes a stream of requests and returns a stream of responses. So I want you to think of -- earlier I said I want you to think of as a function as written once but running as many times as necessary. This is the same sort of thing. I want you to think of as the server that you contact once and get one response from. But then it's the language's job to lift that and take a stream of request and returns a stream of responses. Okay. So once I have get web service object E, it's pretty easy that all I do is I have these requests and when E was the merge of those two streams, well, I'm sorry, it's the argument, which was coming in maybe as a merge, I snapshot the value of doc. I have to snapshot it because I want that instantaneous value. And I have a make request function that constructs some Java script object with descriptors, URLs and all the usual stuff that the server is expecting to hear. And I pass that stream to get web service object E, and I get back a stream of responses. Okay. So that is how I do the saving. But I might want to do more. I might want to also style it. So, for example, we like to draw -- we like to change the border color of the box between saves -between the sending of a save and the acknowledgment of a save. >>: This feels like it has the flavor of starless, the [inaudible] machine in the sense that you have these values that are single variables that like a Q value inside, like what happens if you want to do an if statement on the return value of one of these things, do you just say if say D equals something or do you have to do dollar B of save -- >> Shriram Krishnamurthi: How about we look at the next slide. So perfect setup. Almost perfect setup. I'm not going to do quite an if, but you'll see how the sort of thing you're talking about might get addressed. After the slide we'll get back to your question. So, for example, I want to do styling, right? I want to say depending on the state of the box I want to change the way the box appears. So I have safe D that I have right now. I also pull out all the changes, right? So every time this doc thing changes, I have an event stream for that. I now transform changes with the constant unsaved. I transformed the saved responses with the constant saved and I merge those two. So now I get an event stream that might look like unsaved, unsaved, unsaved, saved, unsaved, unsaved, unsaved, saved, unsaved, unsaved saved. So every key stroke this one keeps getting to unsaved. Every time the server response comes back it says saved. Well, I turn that into a behavior. Start the empty buffer let's consider it saved. I transform behavior, I can now use this behavior to style the border color or style the content or style whatever I want. So I don't -- yeah. >>: So the sum fits perfectly what if the server is unreachable or you dock a connection and it gives you S 1. >> Shriram Krishnamurthi: I actually deleted about seven slides last night about how we handle fault tolerances we have primitives for doing fault tolerance for reject applications. Essentially the idea is you can use continuations and do replay techniques, right, and you can integrate that with Flapjax. And I felt the talk was going too long so I deleted all of that. But, yes, that's an extremely legit -- in particular if we're going to perform on a distributed setting we absolutely have to think about that. I'll get your question in a moment. Andy, I don't know how much this helps with your question. I want you to think of these as point-wise operators. But sometimes you might want to collapse them. So you might want to have an accumulator. You might want to run a filter, any of those things, right? But you never say if saved E. You do things point-wise. >>: You never get to ask, collapse things into single values you would ask. >> Shriram Krishnamurthi: Right. You could do things like maps or accumulators. You've got to be careful about what infinite streams. >>: Mentions time. >> Shriram Krishnamurthi: Right. Yes. >>: If I understand the semantics of this program correctly, when the border changes to indicate that it's been saved it's not necessarily the text you see on the screen that has been saved, because you're actually looking at outdated response. >> Shriram Krishnamurthi: That's exactly right. >>: If you type fast enough. >> Shriram Krishnamurthi: That's exactly right. In fact, so you could take this program and make it more complicated. Actually, no, because -- yeah -- no, that's right. That's right. That's right. Yeah. >>: Basically means saved recently. >> Shriram Krishnamurthi: That's correct. Saved in this case means saved recently. And I would have to define something a little more complicated to say saved and not changed since then. Yeah. Okay. Good. Okay. So let's now try to write web talks. I've got to say something about pipes and tubes somewhere in there. Let's say I want to set up a thing where you type in text. And the text you type is a search string that's sent to Flickr and pulls out all the images against that search string which sends it back which you now display on the page. Again, I'm going to assume I have some Java script functions that take a string and turn it into a request and take a response and turn it into a list of URLs. This is marshalling and unmarshalling, parsing stuff. Pull out a query of text that gets typed into it. I map it to turn it into a set of requests. As you can guess I'm going to send that request off with get web service object E. I'm then going to map the responses with this other pure function or some Java script function. And if I start with the empty list, then what it's saying is that the empty box corresponds to the empty list of responses as I keep typing I get new lists of responses, and finally I can put that into my web page by just inserting it into some development cult dumps. Again I'm doing functional programming but what it's telling me is that every time search changes, query's going to update. Every time that updates, request E is going to update. Whenever that updates, response B is going to update. And every time that updates, the content on the screen's going to update. Okay? So all I'm doing is showing you the same primitives I've shown you before to construct a fairly different application. But there's something really annoying about this application. What's really annoying is that every single key stroke I type, this thing's going to go off and send something off to the web. Right? That's bad. That's really annoying. The web's not really free, right? So, in fact, the programs that we write look just a little different. We need something called com E. Com E is a comminator that says don't bother about any events during this period, this duration. In this case, wait for a second. Let this person keep typing and wait for a second and when there's a second pause, then do something. So drop events until then and filter out the events. And this is a really useful primitive for all sorts of user interactions because you want to avoid things happening too quickly on the screen. So com E shows up all over the place. So one of the things I could do I could actually use something like com E to clean up some of the behavior I showed in the previous slide, for instance. All right. Another thing you can do is take user interface content and behavioral content and package them up nicely. Now, this was supposed to be what object oriented programming did but sort of tends to do pretty poorly and the whole call back style reveals where that weakness is, where that falls apart because you have all these weird control flows between components that aren't properly localized. So here is Resume. This is a job search manager that several computer science departments use. These aren't real candidates, don't worry. And over there you see there's a little filter applicant's box and if I click on it I get a box that looks like this. All sorts of criteria you can filter applicants using. Now I want to show you a little bit how this portion of Resume is written. So I have a function let's say called pick gender. It should be sex but we're Americans, we don't use such words. So I have a user interface component which in this case is a selection box that has two values, either male or female. And I'm going to return a package of two things. A Don component, which is the UI, and a predicate, which is pretty obviously take the value out of the UI. So here lexical scope does the right thing. Take the current value of this, compare it against person gender, for whoever the person is, and give me back a boolean. So that's a filter. I can also have a different filter that maybe is a score and I have a text box and I can do various styling for the text box to make sure that's the way I want it to be I can have a checker for that. Now these are functions that I can use directly, right? So I can take one of these things and separately pull out the UI component and put it on the screen, and the dom component put it on the screen and the pred component, use it as a filter. If, for example, I apply this function using filter to a list of applicants, every time somebody types something different over there, automatically my list of applicants filters. So anybody here who has used iTunes knows you have a little box up in iTunes as you keep typing text the content down here keeps changing automatically you don't have to press return and so on. That's exactly the behavior you get for free by using this. But in fact you also want to combine filters. So, for example, you have a list of filters. And there's a function that says tell me which filter you want. So I create an option that says what the filter options are. A selection box for that. Some filter is just take this selection, look up the corresponding filter, and that gives me back the specific selected sub filter. And what am I going to return? Again, a filter. So the dom is just a span that says here's the filter you selected and here is the dom for that filter. So if you select this kind of filter you get one kind of search box, you select a different filter you get a different search box and the predicate is just the sub filters predicate. Then we have commonaters over this the usual commonaters that's how we compose that big filter box that you saw. This is literally the kind of code that's running there. There's no tricks. No sort of weird parity underneath. This is the code that's running and you compose these to build bigger and bigger filters. Finally, let me show you a sort of mash up like example. In this case I'm going to take Twitter and Google maps. So Twitter is, Twitter people say random stuff on the web, and they put out these things called tweets, and there's a public Twitter stream you can get from Twitter of all the tweets that people are saying in the world. Don't ask. Yeah. And I might want to mash this up with Google maps or Live Maps or something to show where all these things are being said, just to waste even more time. So, for example, I went last night and I started the program and the third thing I got was there's somebody in Boston who is clearly kind of hungry and then a few tweets later somebody's wishing somebody else good morning. So as these tweets keep appearing I want to keep displaying them on the screen. Maybe when I click on the button I want to get the text. I'm not going to show you all the code here. But I want you to understand that there's an interesting principle. The principle is that this is the name of a function from the Google maps API. And you can see my call-back principle being illustrated nicely. So you give it a string that says you know like Providence, Rhode Island, Bangalore, India, whatever, give it a string, and it comes back and gives you the geo coded location for that string, if it's able to succeed. So there's a function of this form. What we do is we take functions like this and systematically transform them into functions of this sort. Okay. We make them typeful, basically. I'm not going to tell you how we do it. And it's actually a little challenging. So if you're really following along in the talk you might want to think about how you might be able to write such a transformer. There's one piece you actually are slightly missing and you should ask me about it if you're interested. But the point is this is something that we can do systematically and we do it one time. So now we have a way of getting events -- I have a way of getting a geo coder that takes an event stream of locations and gives me back an event stream of geo codes. So I guess points should have been geo code. So I have that function. I'm actually going to give you a slightly different function. It's also going to carry some additional data if I need to. So take some additional data and gives me back that additional data just passed through polymorphically so I can overlay additional information just beyond the location, such as the tweet. And similarly I'm going to get a get Twitter pub tweet so take Twitter's API and turn it into an event stream and also a map overlay which is take an event stream and overlay it on the map. Now I've got event streams everywhere. So I get the tweets. I map this function over here that basically takes the tweet, passes it to Google, and gets back the geo code for that tweet. Right? So this is just the transformation from the Twitter information to the Google information. And now I have to filter out all the ones that came back with false, because sometimes you give it the name of a string and it says I don't know where this place is, because Twitter's not giving it quite the right information. You filter those out and you overlay it on the map. So this is really sort of really you want to think of it as classic Unix style shell programming, except I can do this also from mashups. All right. So what I'm trying to do is give you a feel for what it's like to be a programmer in this language. You think functionally, but you get all the benefits sort of object oriented program and USB typing and so on that work in just the right way. And most of all, you get the right what are essentially functional specifications that say here's the one-time behavior of what I want and if something changes make the language do it for me. So I'm going to leave you with one more abstraction, and this one I'm not going to show you any code at all, because I really want you to think of it as a challenge. So the dom, as I told you, provides events. It tells you about mouse ups and clicks and so on. And every programming language, C# comes with a bunch of things, Visual Basic comes with a bunch of things. But it doesn't give you complex things. It has a bunch of primitive events and that's all you get. So, for example, it doesn't give you drag and drop as an event. But that's a reasonable thing to think about. In fact, it's a reasonable thing to think about because you're using all sorts of contexts when you're building GUIs. For instance, if I drag over there and drop, I mean I want to move the buffer or move the window. If I drag over there and drop, then what I'm saying is I want to resize something. Or if I drag over there and drop, then what I'm really saying is I want to select something. So if you're building a GUI that has these kinds of operations it's really useful to be able to think of drag and drop as a primitive then you can ask contextual questions about where you're dragging and where you're dropping to figure out how to interpret this. And you might even want to do different interpretations depending on other circumstances. So the challenge for you, if you have a programming language, a favorite language, is how would you encapsulate this as an event of some sort. Whatever the event encapsulation of your language is. And if you're curious about how we do it in Flapjax, we have a section on this on our paper and we show how to get this as an honest to goodness abstraction. You can say this is a drag and drop event stream. So speaking of your question about types it's an alter nation of drag events and drop events but it's still an events stream. And we can actually then write a whole bunch of functions, think of it as like -- you get this visitor kind of abstraction. You get a type and then you can write functions against that type. Here you get an event stream and you can write lots of different functions that plug into that event stream. So it's giving you back that functional abstraction capability. All right. Good. So this is actually a little complex, which is the real reason I'm not showing you the code. I'd love to but it will take about three pages and that's too much code. So I want to start wrapping up what I've said in this talk. One of the nice things that's happening is other people are beginning to realize there's value of thinking about the Internet as a communications of event streams, opera actually published this API. It's not a very good API. Hasn't really caught on. But I think over time -- people who build web servers are sooner or later going to start wanting to publish better APIs than they do. If you think about atom feeds and RSS feeds they're getting to this idea they just haven't sat down and formalized exactly what they mean. The world already thinks this way. In fact, if you think about these behaviors, if you programmed in Java script you already have a behavior even if you don't program in Flapjax. It's called a dom. Because if you think about the dom, any change I make to the dom automatically gets propagated to the page. I don't have to make a change and then notify somebody to then go off and do the update. Anything I do to the dom is automatically propagated out without any additional effort. So you can think of Flapjax as saying, well, why is it that only the dom is this privileged data structure that gets this capability, why not hold bunches of layers that get this capability pushing all the way through and ending at the dom. That's one way to think about what we're doing is generalizing that principle. Yes? >>: So what characterization you're doing, is you're taking time as a dimension and you're making it explicit, basically. Things are changing through these events or whatever. And your abstraction is exposing that. So every slice of time you're doing things essentially and you compose, it gives you this compositionality, what it doesn't give you is the simplicity of reasoning about just one state change. I mean, in other words you lose the ability to think about a single -- I go from this to that, respond to a single event, to I have to think about the fact that now I have a stream of these things. And everything I do has to deal with the stream. So I think it's great. I'm really excited about the idea that you can get this abstraction. I think one of the barriers to acceptance is going to be this kind of change of thinking, not just about single -it's like sequential program -- function programming you think about maps and higher order functions. Most programmers think about I make this change and it's ->> Shriram Krishnamurthi: I changed this one variable, yes. Yes. >>: I think it's a very similar kind of -- >> Shriram Krishnamurthi: I think you're right. In fact, what happens is as I've actually gone through this exercise several times of trying to write a program in a completely standard Java script style and then slowly transform it into Flapjax. So one of the weird things about Flapjax is we offer it as both sort of a language that does some of this stuff for you automatically but also as a library so you can just program in Java script or with this as an extra library, or what do they call them, kits, I guess. Some term that Java scripters like to use. Anyway, I've gone through that experience. And it's actually not completely trivial even with my experience to do that, because what it's doing is it's forcing me to say it was really easy to write this one step, okay. But then as you say. But then the problem is I don't know what my sort of long-term behavior is and in fact I get horribly confused because it doesn't seem to be exactly what I expected it to be. So in some sense what I'm doing -- we had the same experience of continuation-based web programming. Is we're going to put a slightly greater burden on the programmer. What it does is reduces the burden on all sorts of downstream tools. So verification tools. So we built a model checker. We built program analyses and so on for our web application framework. And it became a lot, lot easier because we made the programmer do this little bit of extra effort, right, of not just sticking everything in a string saying I'm done and when I have to restart I'll figure out how to pull all my data back maybe it's not really there I'll figure out what's going on. It's the same way reasoning about this with a theorem proffer is much easier because you can do functional reasoning but it does push the burden onto the programmer and that's not always a popular thing. >>: So coming back to that analogy with the dom that you made, one of the nice things about the dom is that it's one data structure that's persistent across multiple [indiscernible] so even if one of them fails you still can go back to the dom and do something acceptable. Whereas what you're saying is the entire code has a semi process property. So as a programmer, I would think that the burden of showing that nothing fails is much higher in this case. Do you agree? Disagree? >> Shriram Krishnamurthi: Hmm, well, I'm not sure that that's necessarily true. Because if I have some -- if I have some behavior attached to a timer, say, I've got some timer that's running over there. Let's just say I happen to have an error in my function that's attached to the timer. The next time the timer fires, that function is going to be called again. I might have some piece of code that has errored out. I would argue that part of the problem with Java script is little weird things happen, piece of code error out and other pieces continually happily running, even though the world may be in an inconsistent state. So I think we're at least in a better position to say this is running against an inconsistent state, because there's some expectation of what the state was supposed to be. It's the property as I said the expression is the value is always, can be computed simply from the functional expressions. At least we have a chance of saying the world is running but it's an inconsistent state and you might want to be aware that the output you're getting doesn't quite make sense. In contrast to traditional Java script where you run your program and you've got this web page and things sort of run and you click on a button and nothing happens. And you go to the error console. I like to ask people do you know where the Java script error console is. It's shocking how many programmers don't even know there's an error console. You open it up there's like 20,000 little yellow triangles and one red thing saying there was an error. And it's some weird property and undefined. The other thing is Java script is also part of the HTML culture of try not to make things error out, right? It's actually hard to get Java script to give you an error. You can say undefined dot method now it says now I can't just make up nonsense. But short of that it's hard to get it to stop and say something went wrong. So I'd argue that that's not such a good thing in the first place. And having some sense of what the state of the program is supposed to be made might actually save you a little bit there. >>: I agree if you are making all the core [inaudible]. >> Shriram Krishnamurthi: Oh, I see. I see. >>: Boarding other code and stuff like that you want to make sure that one of them doesn't end up breaking the page or breaking ->> Shriram Krishnamurthi: In that case you would just have a whole bunch of separate event streams. One of them is breaking. As long as you're in one of these mash up cases where you're trying to achieve isolation. You have all these different mash ups that are presumably presenting event streams. You're creating like an I Google kind of page or something like that. These each are printing event stream so the breakage of one thing doesn't completely affect another. And in fact I would be able to tell you that. I'd be able to tell you that this value -- this is the cone of influence, or this is the cone of contribution for a value. Right? It's all of these expressions. So the error is outside this cone. You can be sure that your value would not have changed whether that thing ran or not. That's harder to achieve in Java script because you have to do a program analysis through a dom model to figure out whether that's true or not. So I'd actually argue that you're making a good case for the style of programming. But that's a rhetorical point. Yes? >>: Perhaps. But it still seems like it's possible to end up with too much activity. >> Shriram Krishnamurthi: Yeah. >>: So presents some -- so the worst case is [inaudible] sphere of influence, screen can be touching on the dominance, dominance is a giant structure that everybody's touching unless you high frame everything you are basically sort of back to square one. >> Shriram Krishnamurthi: That's right. That's right. >>: Another thing is that there's some inclusion in [inaudible] shops. There's also a possibility of I don't know denial of service some sort of thing where you have this superfluous activity, something that you think they don't quite expect. It's going to [inaudible] off on you. >> Shriram Krishnamurthi: I won't begin to pretend that Flapjax is giving you a handle on getting good web isolation. All it's doing is in the case where something is sort of half broken, it can tell you whether or not that brokenness affected you. But the isolation problem is -- this is not solving that problem. >>: It's not the isolation problem, though, maybe the issue the light changed, you observed a previous indication error. >> Shriram Krishnamurthi: Yeah, yeah, yeah. That's right. That's right. >>: That's a possibility. In fact, you asked the question about talking to servers that might be flaky. That's sort of what happens, we have this retry-based model. Essentially think of it as a transactional model. We want to know which invocation point were we at, which time through the invocation point and which retry were we on. That way the server and the client are able to tell whether our state is synchronized or not. There's a triple that basically identifies the unique point in the computation and each of those transactions can then be retried precisely because it says I haven't been heard back here's a tryout policy go try to do the retry of the computation. Okay. A few more things. I keep sort of alluding to functional programming and is this purely functional. But it's a weird thing, because it's functional programming over imperative values, right? And normally that makes no sense, except in our case we're saying it's functional programming over imperative values, but because the changes are automatically updated, you don't notice the fact that the values are imperative. But in fact you can actually introduce imparity into the program and I've been doing it since slide one because that's what snapshot does. So consistency is a primitive. But snapshot says stop evaluation of this little sub expression. I want to know what it was then, as opposed to what it is now. So one question we can ask is: Should we be snapshotting by default? Because that's what traditional programming languages do. Right? In fact, I would call a variable as sort of a failed behavior, right, aspiring behavior that never made it all the way. Behaviors are variables that don't have this problem. And we've looked at lots of our code and we find the number of snapshots we use is roughly one to five per thousand lines of code. And this is actually old numbers, there's many more applications now and it seems to be consistent. So you could argue that maybe having snapshot as the explicit operation rather than update being the explicit operation. The bug by the way, did anyone catch the bug in the initial slide thing? What happens is you propagate, when you click reset, it propagates to the variable but doesn't propagate to the string. When you click reset nothing happens on the screen until the next time the clock goes off. Then it starts at 1 rather than starting at 0. Precisely because in some places you knew to take that value and send it to the screen. In other places you forgot to do it. And I must admit, by the way, it sounds like a setup, but actually I made that bug in the program myself, and said aha, good so maybe it was self conscious. I'll end with a sort of purely rhetorical slide. So this is Eric Meyer runs the software radio something, something, and he went and interviewed Simon Payton Jones. So here's Simon. So Simon -- I can't do this sort of Simon accent so I'll do it my way. Simon draws this graph, right? And he says look, there are languages, and they're on a spectrum from useless to useful. These are Simon's word, not mine. Simon, if you're there, hi. There's another spectrum here from sort of unsafe to safe. And so he uses the phrase, this is literally his quote: Unsafe means any effects anywhere and unsafe means limited effects maybe even no effects. He said I'm going to start plotting languages on this graph now. So C and C#, Java all of those things start out over there. I suppose that looks a little like Mickey Mouse. That's coincidental, I guess. This is Simon saying this, Haskell is over here. So in its purest form, Haskell is like all the way at the bottom over here, sort of at this corner. It's extremely safe. But you don't even know if it's running, maybe you put your hand on the computer to see if it gets warm, but even that may not be -- nothing happens. But the point is that Haskell has been moving upward. That is, it's been adding effects in a very principled way. I actually think Monet is kind of a losing, Monets, I've got lots of issues with Monets, but the point is the Haskell community has been working upward here. But so have those languages, they've been moving sort of to the right, which is separation logic or ownership types or any of these things are basically saying completely unfettered affects everywhere not such a good thing. Transactional, transactional memories that sort of thing too. Maybe we can think of things in a little less effective manner and the language a little more ability to reason that would be a good thing. So natural question is where does Flapjax fit on this slide. Well, so I'm going to say I sort of reject this diagram a little bit. Because I think Flapjax, I'd say I told you it's a rhetorical slide, I think it belongs somewhere around here. Because it's obviously a useful language. I mean people have built applications with it, even we built applications with it. But it's very much along the sort of right end of this. It would seem to me to be a simple parallel axis over here and everything has to be in this lower left hand triangle. And yet I claim Flapjax is a little bit outside of this triangle. And I think it's because I don't entirely buy this phrase very limited effects. I mean, it's not even clear to me why effects are a bad thing. I mean the effects the computer is actually doing work and making themselves useful to us. I don't think that should be considered a totally bad thing. So it's a question of what this phrase really means. Is it very limited effects, or should it be maybe limited observable effects. That's okay, seeing effects that's just observing output. That's not a bad thing. Maybe it's something more than like limited nonalgebraic effects, things I can't reason without using algebra and composition. Maybe that's the problematic thing and in that circumstance again Flapjax gives you pretty good algebraic reasoning while still giving you the ability to write effective programs without having to go into sort of an IO Monet or something like that. I don't know what this picture should look like. It's more for conversation than anything else. But before I take questions I'll just say that somebody else has to do the work obviously, because I just give talks. I write code occasionally, but somebody writes more code than me. These are the guys who did it. Leo, the lead author for Ajax, is coming here in two weeks to work with Ben. So that's awesome, a good choice. Questions, comments, anything else? Looks like you were about to say something about that previous slide? >>: I guess the characterization -- so what is your thinking along, in terms of the cast of dynamic types. You're talking about side effects, right? >> Shriram Krishnamurthi: This is purely about side effects not about types at all. >>: People would say dynamic types are a source of inability to reason and also safety, right? Basically. So it seems like that's not even in your ->> Shriram Krishnamurthi: That's not in mine -- partly because I was just quoting Simon. But also I would claim that static type -- there's a difference between types and safety, right? Static -types are syntactic discipline. Reynolds always said this. Types are a syntactic discipline that you might run on a program. Safety is a concept where you have abstraction boundaries in your language and whether the language enforces them. How it enforces them is the responsibility, it's some combination of factors. Even in a statically type language. It's still the case that not all of them obviously can be enforced statically so that some of them must be enforced dynamically. So in some sense a scheme programmer is much closer or at least a good scheme programmer is much closer in mentality to an ML programmer, than to a C programmer. Because the scheme programmer still believes it's good to have abstraction boundaries, it just so happens they're all enforced completely at runtime and it can be sometimes problematic. As opposed to I don't want abstraction boundaries. Or put differently, I have only one type in the universe and then there's no abstraction boundaries to even speak of. And that type is like the 16 bit word or something like that. In fact, CI claim is a very peculiar language. Even the notion of talking about soundness of CI claim is a very strange to talk about, because normally when you talk about a soundness theorem, you're starting to say there's some static discipline that's trying to mimic what's happening at runtime. I have runtime behavior that corresponds to it. And the soundness theorem is saying this accurately simulates what's happening at runtime. But that's not how C works at all. Right? C actually has two type systems. It's got a static type system that has things like nth and bool and words like that. On the dynamic type system, all it has is 16 bits or 32 bits or 64 bits. And you can't even ask is this thing one of those things. So the notion of soundness is meaningless, because the runtime types and the static types are totally disjointed universes. So you can't even call -- C is not even unsafe, right? It's something beyond that. >>: Beyond unsafe. >> Shriram Krishnamurthi: Beyond unsafe. Beyond mere distinctions of safety and unsafety. I want to make a distinction between safety and typeness. And the other thing is also there's this worse situation where you have a static type system but it's not safe. It's not a sound static type system. You run this thing and you think you're getting a guarantee but you're not. Right? And those languages exist, too. So I would claim that we really should separate out those concepts a little bit. But I think static typing is a good thing, by and large, and tomorrow I'll say a little bit about it even. >>: I wanted to ask you about it's a related question on safety, foundations, building and couple of things. You're building this language [inaudible] overrun time. And you don't really know all that much about [inaudible], first of all, you're thinking about seconds, and the approach of real time guarantees ->> Shriram Krishnamurthi: Absolutely. >>: You don't know much about the order, and you don't know much about a few other things. >> Shriram Krishnamurthi: Absolutely. >>: So could you in this work, did you work out a set of suggestions for better set of runtime [inaudible] perhaps. >> Shriram Krishnamurthi: That's a good question. No, because we're trying to do something sort of dirty here, right? >>: You have to do something dirty? >> Shriram Krishnamurthi: That's tomorrow's talk. I would start with trying to get the static types cleaned up and go from there. Because again I'd need some -- to get guarantees I want to talk about static and dynamic guarantees as part of a continuum, and so that's why we're doing the type system work. So you're right, even in father time, right, technically father time is built on top of doctor scheme, which I should know a lot about. What is doctor scheme; 700,000 lines of scheme code and another 100,000 lines of C++. Who the hell knows what these things do. In some sense getting any notion of guarantee out of a modern runtime system seems to be slightly wishful thinking. I know there's people in this room that built amazing runtime systems. >>: With the Java and [inaudible], it's attempt to implement the specification. >> Shriram Krishnamurthi: That's right. That's even much worse. It's also which jobs for runtime, because there's the Java script runtime and there's five different browsers and each of them ->>: If you had to answer a question, if you had to define one. >> Shriram Krishnamurthi: I agree. I don't know that this work is produced much more than by recommendations maybe other than take the Java runtime and translate it or something. >>: You made a strong case of why you start using Flapjax and designing pages. What if you had [inaudible] overhead ->> Shriram Krishnamurthi: So that's why we provide it as a library, right? So you can go in and say I've got this element over here and I want to make it reactive. So the library design is a little careful that way, if you said dollar B and I attach something to an event stream which leaves the existing call backs in place. I mean the implementation is by adding call backs to the existing call backs, by chaining. >>: What data are you provided for that -- because each function may do ->> Shriram Krishnamurthi: So Flapjax was intentionally, other than like father time, Flapjax was intended to be a real world compromise. We could say we could reject all programs that are not pure functional with Flapjax and I think that would be useful. We do provide some ordering guarantees, because if you write something imperative and you launch a bunch of events in an imperative sequence we provide some ordering guarantees there. So that much we have. But we don't say anything about completely random code that we can't see. And we could. But I know what to say but we haven't bothered doing it because that would mean doing program analysis of Java script, but that doesn't exist until tomorrow afternoon. Yeah. >>: So whenever I see a talk on so-called visual programming, they tend to, because it's what you can express as a graph, they tend to come to the sort of programming manager, events for using -- and he thought about well since that fits, making a visual. >> Shriram Krishnamurthi: In some sense that's what Yahoo! Pipes is trying to do. Yahoo! pipes is a visual language where you can drop events and plug them together. And they've done a lot of work on trying to parse like the 25,000 different web services out there and so on. It's still a very discrete model. It doesn't have this notion of behaviors. I think we could, it was sort of -- anything we produce would look shabby compared to Yahoo! pipes, wouldn't be able to compete with them. So in some sense we're like pipes for contextual programmers. Yeah. >>: If I may. >> Shriram Krishnamurthi: Please. >>: I was going to ask you about the upper pipes as well. What their evaluation model doesn't seem to be nearly as good as yourself. >> Shriram Krishnamurthi: They don't offer any kind of semantic guarantees with the evaluation model. It's like -- the behavior is whatever the program does by running. So we could in principle maybe steal the UI pipes UI and put Flapjax underneath it and that might be a better alternative. That's true. That's true. Other questions? Okay. >>: So how far is this program modeling different from the [inaudible] reactive ->> Shriram Krishnamurthi: Yeah, there's several ways. The evaluation model is different -functional programming is, our underlying inspiration. But, for example, there's no FRP work that says here is how you take an OO library or some OO primitives and lift them automatically to a functional log. They don't have to think about that. We provide it as a systematic thing you can do. Most of the FRP world work happened in the context of Haskell where you get event streams for free, but they don't have to think about what called by value or valuation has to do with this. What I think we have is a severely clever way of embedding the graph construction project as a called-by value program. So we sort of transform your program into a call-by-value program whose execution automatically builds the graph and then runs the graph for you. So that's a pretty big deal, because it means that I can give you -- give you certain guarantees, how this program's execution matches the underlying Java script execution model or the underlying scheme execution model that if I had to write a hand interpreter or something I wouldn't be able to get those kinds of guarantees. So we're very inspired by it, but I would say we've gone in many different directions from there. Called by valuation, the push-driven model. The object oriented connections, the optimizations we've done. So part of it is if you do this naively, we had a paper where we showed a speed-up by not percentage but by factor of 68. Okay. What that tells you is if you do this naively it really sucks. When you see a factor of three, it's like, wow, that could be clever. But if you see a factor of 68, you know the original was really dumb. I can't take too much credit for that. But we've done things like that. So all of those are all novelties that the original RP work didn't have. They did great stuff and more power to them. Yes, very good. Thank you all for coming. And thank you to whoever is out there for coming too. Thank you. [applause]