17116 >> Ben Livshits: Let's get started. Thank you...

advertisement
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]
Download