 Cool, so I really like Undo, while ago I found this program called BPython that has Undo, and it's Undo works, or BPython's kind of nice, as you can see I have some tab completion here, we've got some fancy other things going on, but my favorite feature is that if I make a mistake here and I accidentally call this method with the wrong arguments, oh I can make that go away, I can get that screen real estate back, and I'm not even just, I'm not even, I'm actually unbinding variables here, look at that, A is gone, how does that work, what is going on here, this is super cool, so when I found this I wanted to know. And maybe someone wrote a fancy Python interpreter where in, like if you pop an element off of a list, maybe we remember what that was and we can append it again if you Undo, but then the ref count, like how does that all work? And the answer is that's not at all how we do it. Instead, if you have this state in your terminal and you're trying to go back, you're trying to undo, let's just start Python again and run the same commands minus that last one and we'll end up with a state very similar to what we would have had we undone. So this is a pretty, it's kind of this nice, fairly general strategy, so replaying state by replaying actions. And once you have the infrastructure for this, you can add other things, cool things like, ah, if I have a terminal state, maybe I could go back, throw this in a text editor, edit a function, and I'll have see what the implications of that work. Maybe I could have automatic, like reloading where I have a file and I could change a function in that file and watch that file when it changes, we could change the output of running that function. So this is a powerful idea that goes beyond just Undo, it's kind of being able to modify our program at arbitrary points. So pretty cool, pretty general idea, here I threw together a Haskell version of this, so any interactive interpreter you could sort of imagine working like this, but there are some sadnesses associated with this method of Undo. For one, it takes time, so maybe you're doing something, here I'm building a couple, 10,000 numbers, and I get to Undo and it says, Undo's gonna take one second, and maybe it could be 100 seconds, right, the amount of time that it took humility to run all of those previous things. So that's a little unfortunate, I actually added that message that says it's gonna take one second to be Python because it was frustrating that it would just freeze there, and this way you can Undo multiple lines to avoid the n squared problem of repeatedly Undoing like that. Another sadness here is that there are nondeterministic actions that we do sometimes in programing languages, we've got time, I've got random events, maybe you're gonna ask for the memory address of this list in Python, maybe I'm gonna read on standard in, that's what input does, and all of these, if I try to Undo in a sec, you might see them change, or I'm gonna get a different time, a different random number. Interestingly, so here we go, here are our different numbers, you see things changing, so output of your program could change because of that, I'm actually caching the input, it seemed like in an interactive interpreter, maybe you want to cache readings on standard in, but it would be a lot of work to go through and cache all of this stuff, anytime your program interacts with the outside world, every syscall are we gonna kind of mock that out, so that seems like a lot of work. And then there are nondeterministic actions that are gonna run again, so maybe here, let's see, I'm gonna import this, create a temp file here, and, oh shoot, I just lost my train of thought, I need to do a quick errand, I'm just gonna buy some shoes real quick, because I just thought of it, so I need to do it right now, but, sorry, or ASAP, okay, okay, but let's go ahead. So, not yet, not yet, so I'm okay, I'm gonna buy the shoes again, buy them shoes again, so the thing I'm actually worried about here is that these temporary directories, right, I'm created a temp directory, if now I run some code, and then I go to undo that stuff, I'm gonna end up with more temporary directories, because that was a side effect that happened again, so every time I do this, I get more temporary directories, and this isn't, oh great, my shoes are, oh, my shoes are pretty big, it's great, oh, but I didn't, I didn't want, I didn't want four pairs of shoes, what, what, shoot, intended. So there's our, oh no, right, temporary directories aren't a big deal, they get cleaned up when we close Python, but more shoes is, maybe you hit the network, maybe you do side effect-y things, you don't actually want to have it multiple times, so that idea is out. Let's try to save our state and restore it on undo, lots of programs can do this, MATLAB or R have built-in functions for serializing your state, and you can reload it, although it might take a lot of space to do that, and in Python we don't have something like that built in, so I wish we could kind of efficiently store the representation in memory of our program, well there's a thing called fork that could do that, so maybe we took our program and we forked it, we made a copy, so this makes a copy of a process and the memory associated with it, but the operating system stores it efficiently for us, so let's fork our process, prompt for input, do the thing, I'll just show an example, over on the right-hand side here I have PS Tree, which is going to show us the processes and the child processes of something, and on the left-hand side we're going to do something and then I'm going to try to undo it, you can see I'm getting more processes, fork, fork, and I get these different copies, and in the old versions, in the parent process it's still that original state, but in the child process it's our new state, so I can say undo and see is undefined now, I can undo a few more times and we see all those child processes die and be is undefined, this works pretty well, the terminal state's not great though, so let's use a pseudo-terminal to kind of capture the terminal state here, and now if I say undo we'll actually get the old state back, and this is a pretty common thing, we could do this in a lot of programs, a lot of interactive interpreters, and I can actually encapsulate these changes in a thing called ReadLine, which is a C-Library, lots of interactive interpreters use, the patch looks like this, and I just have to recompile my different interpreters with this, and I can add undo to almost anything, except recompiling is kind of a pain, so I heard about this thing called LD Preload, which is pretty neat, I was sort of worried about it at first, but then I googled that it turns out it's fun and easy, so that's great, so I went with it, and now you can have undo in any interactive interpreter, which is terrific, here we have IRB, the interactive Ruby interpreter, and I'm going to try it, I hope it works, A, B equals 2, let's try to undo it, great, it looks good, and it's not defined, terrific, so we have undo in lots of interactive interpreters, and it works real well, don't worry about this, it's just when you try to quit, and if you don't quit it's fine, just stay in your rebel, and this basically works perfectly, which is terrific, so Larry will, it doesn't work perfectly actually, so I wish I could do this really right, if we build an interpreter from scratch, I think we'd kind of pull this off, I'd really like to have kind of long running programs I could undo, and by doing these snapshots we lost an important thing, which is being able to edit previous lines of our sessions, so I'd really like to be able to do that again, if as long as we're recreating a universe, let's say no action's going to escape the box, there'll be no shopping for shoes, API, and this new interpreter going to build, I want to change any part of the program and see the effects immediately, I don't want to wait for them, so I'm going to use both snapshots and maybe efficient copies, I don't know if I need a lot of stuff to do this, it's going to be a lot of work, so we do that work, we made a Python prototype, did a lot of bytecode debugging, and then voila, we've got this interesting environment, kind of written in JavaScript where we have an interpreter that you can rewind time in, because all of those are snapshots, we took all those snapshots, we can go back, we can step through because we have deterministic replay, the caching we talked about before, stepping backwards is actually going back to the previous snapshot, deterministically running up to that point, so we're using those ideas from the two undo techniques we've looked at before, we can make this kind of interesting, powerful thing, and we have a run program from here change the future, which is the combination of, I want to change something early in my program, but I don't want to rerun it from the very beginning, I want to take that snapshot, the last time that thing changed, run from here, and we can use these tools to make this thing, dalsanio is some kind of music pun, if you get it, but here I'm playing golf, I'm gonna throw my golf ball, oh it didn't quite make it in, I wish I could tweak the code that did that, and I wish I didn't have to restart my program to do it, so if I just change this fire function, and I remember the last time that function ran, I can resume execution at the last time that function ran when I edit that code, so this is kind of this powerful idea of, if I'm changing initialization code, I'll have to go all the way back to the beginning, right? If I'm changing code, so here these are global variables, all the way back to the beginning, if I'm changing code, it's the draw function, I have to go back one frame, it's very instant, if I'm changing code that has to do with bouncing off of the paddle here, then I'm just changing the bounce function, we know the last time the bounce function ran was the last time it hit, and so each time we get this instant feedback, it's like tweaking code like it's CSS, and just playing with things, but there's this tension that a normal way games like this is to have a main loop and you'd call all the code, run all the functions every frame loop, so it's not super useful to rewind to the last time you call the function. So this paradigm doesn't work quite as well, so maybe we could do something with running, so this is the problem, we have code like this doesn't work well with code like this, a synchronous blocking of a bunch of actors, each one's running their own thing, the undo I described would be really powerful here, the rewind to that previous state, so what if you had a bunch of little actors and they're all running their own little programs and then you could tweak them and rewind the state back, see these effects immediately, so it made a little prototype of this over on the left hand side, you can see the scheme code that you could be modifying, you can see some undo here, each of these little missile things is running its own synchronous kind of program in this interpreted language where we can have the rewind and you can modify that code, but we still have a big issue here, so this is our language, you'll notice there's a lot of parentheses, and if there's a thing we know from program language history, well parentheses are okay, but the word has to be on the left side of the first parentheses, if this thing's ever gonna be popular, so let's take a JavaScript interpreter instead and we still have our efficient interpreter but we're gonna change an existing JavaScript interpreter to kind of record function executions, we have to copy state, and now the user can write JavaScript and we still have our powerful undo-y thing where I can see which code is running, if I fire a missile, I can watch the missile code down here running, but because it's this blocking thing, this undo works real well where I can say let's resume execution at that last point in this, and then spaceships, I promise spaceships and the thing, so you can put some spaceships, sprites on and it looks kind of cool, but this is my attempt to, like this pure version of undo such that when you make a change, we rewind the state and you can kind of tweak the constants in your AI code for your missiles and see what happens. I have some credits and things and that's it. Thank you.