Well, the idea that data can become code that has malicious effects is certainly a sobering idea. There's many, many positive practical implications of von Neumann machines that overwhelm us. So again, in von Neumann architecture there's no difference between data and instructions the same word can be data one moment and an instruction the next. And immediately, early programmers realize the advantages of this. So, we'll talk in detail about a couple of these things. One of the first things was that once you've got a program keyed in with the switches, you can save it on physical media. It's just data and you can put it out on physical media and then you can load it at some other time just like we loaded the array, you can load your programs that way. So, a program you might have to enter with switches only once and then you could save it and load it at another time. And in fact that's how program development was done. Come in in the morning load your program, work with it by adding more routines, patching it to jump out, and then back in and so forth. And then at the end of the day save the current state of the program with another dump. And not too long after that in fact, actually very early on people realized that you could develop higher-level languages. And we'll look at just a simple example called assembly language which made programming much more palatable on these simple machines. Advantage of being able to treat code as data, data as code are really profound. So, here's the idea of dumping. Again, we spend all day entering stuff with switches, but at the end of the day you have to turn the machine off. Vacuum tubes can't be left on all the time in fact the reliability of vacuum tubes was a huge problem in the early computers. So, what people did was write short programs to dump the contents of the memory to tape. And again, this code here is a simplified version of the code in the book which can do partial dumps and this is a little more general. But this is very much like the code that we just did for loading an array, except in the middle location for there's 9AFF which is to write the current word to standard output. And this is a program that just sits in a loop, printing out the contents of memory as long as from 10-FE. FF of course is the standard input/output location that we don't need to dump. So it dumps the whole memory to paper tape. Now, this program we put in the first part of memory and then we just run it to save the data instructions and the rest of the memory. Now, this pseudocode uses 0x10 that's a hex literal in Java code that maybe we haven't used but we will use a little bit later on. 0xFF is also used in the pseudocode. So, that's dumping a small program that we can implement then we put in the switches to save the whole contents of memory. And then the next day we reboot the computer we turn it on. At the time you turn it on everything is zero, because it just got turned on. And then a programmer would key in this boot code, which is just like the dump code except that instead of writing from memory to the punch paper tape, it reads from the punch paper tape into memory. Again, using indirection very much like the code that we looked at for reading an array. And then just run that and then it loads up the whole memory, you don't have to key in the whole thing. And again, you don't want to worry about the first few words of memory, because you want to overwrite your own program. That first few words of memory were always reserved for the boot code. And in fact, a lot of computers of this kind would have this boot codes scotch tape to the side, because the first thing that people had to do every day was come in and turn on the computer, key in the boot code, load a paper tape and then get their big program loaded, and then go ahead and do their work for the day running the program on different date or debugging a program. In fact, the early programmers would do this every day or multiple times a day and people would pride themselves on how fast they could enter this code with switches, with the switches on the front of the machine. It's like playing a piano, you'd be surprised how fast people could get at entering code particularly the same one every day in this way. So, that's dumping and booting and it was definitely a critical part of the workflow early on, but all made possible by the idea of a von Neumann machine. But then people realize well, actually we can conceive of a higher-level language that we could program in rather than putting in numbers. We could actually work on what's called assembly language. Where we have mnemonic names for the instructions like LA for load address or A for add or S for subtract, BP for branch positive and so forth. And then we could use symbolic names even for the memory locations or the registers, so that we can have the idea of branching to loop and labeling and instruction with loop. So, then we're not working with numbers we're working with letters that when there were lots of opcodes that was helpful. And we could work with symbols not numbers for the addresses. And one of the big advantages of this is that, the code could be moved somewhere else in the machine without having to actually change the source code, because we'd have a program called an assembler that would figure out where the program starts and the memory, and therefore what the value of a symbol like loop would be. Those were big advantages that made it worthwhile to write a machine language program to translate. And you could write TOY code that could take input like this with proper encoding for the symbols and so forth and produce the machine code. In fact, on von machine they early on had an assembly language in this way, because it was so much more convenient to write in a higher-level language. And again, this is a program that produces a program that has output and again made possible by the concept of a von Neumann machine. People still write code in assembly language today, because it directly maps to machine language code which is extremely efficient it's important for performance critical applications. And that's just the tip of the iceberg. Nowadays, we use programs that process programs all the time. Again, if you have an installer and you're downloading an app, that's a program that loads a program into your machine. The compiler translates your Java program into machine language. Simulators take code for one machine and make it pretend that it's another machine. We'll look at that in a minute. You'd have compilers on a big machine that would produce code for a little machine. Now it's often very useful way to go. Dumping and booting, well viruses, we have that problem but the idea of virtual machines and high-level languages is an extremely long list of practical implications of the idea that we can treat programs as data, and it's certainly a critical part of our modern infrastructure.