 So it's great, I think. So the tool he's referring to of the Max MSP is this data flow language where the data flows across wires and connections. And you can see what you can do if you give people the tool that they can work with, the language that they can think with. The abstractions, the boxes, and the wires come naturally. I don't know if you caught that, but they were not just playing samples, but actually synthesizing the sounds or doing sort of almost physics simulation of the strings that vibrate. So it's pretty impressive. We'll talk about data flow languages later in the course and, in fact, implement a simple data flow language in a browser to replace the ugly event-based programming that you saw before. So the events that flow through the browser will visualize and, in fact, program as wires connecting various functions. So project number four, which you could work on, is you look at programs written in C, say in the Linux kernel, and you realize there are many bugs of roughly the same kind. So I don't know if you can look at the code and see what bug is lurking there. So what bug is there? So we created an object, and this object is here, and X points to it. Now you make Y point to it as well. Now you free the object in here. So using this pointer, this piece of memory is deallocated and could be in here given to somebody else. And now X is still referring to the original location. And in the meantime, the original location could be given to somebody else. But this right here will clobber this memory and potentially crash the program. Whether it crashes it each time or not, it really depends on whether the memory freed here is actually given to some other object or not. So the approach to fixing these bugs is build a tool that for every piece of byte that you allocate to some object, you create a shadow bit somewhere else in the memory to know whether that memory is allocated or not. And now, when you come to this point, X has a pointer to some part of the memory. But now you know that this part of the memory is allocated, but also at the same time freed. This is the crucial thing, that you know that what X is referring to has been free in the meantime. And this tool, which you cannot probably run in production because it slows down the program quite a lot, tells you that at this point, you're accessing memory that has been freed. And therefore, there is a bug in the program. And you can start executing the program again and finding that place where the allocation, the free, has happened. And the way these tools are done, I essentially binary translators. They take your original program, the executable. You often don't even need the source code. Rewrite it so that each time you allocate memory and free it, you don't do just the allocation and free, but you do the extra manipulation in the shadow memory, which sort of keeps the bookkeeping of the program state. Just for the sake of finding these bugs. So finally, you want to be a tool that is better than the PowerPoint animations that you may not actually work with. And the way you do it, that you develop a little domain specific language for just doing PowerPoint presentations with animations. And you embed them in Ruby. Let me show you what these animations might look like. So here is a slide that starts with the text. And now I'll go down and actually let me go to the beginning. It starts like this. And now we can animate the text like so. So I'm going back, going forward. There is another animation here and so on. So you have animations like that. Potentially, you may want to move things. But you would be often happy just to put pictures, graph, charts, and text animation without having to touch a tool like PowerPoint and generate a PDF file in the end, which is what this tool does. So the way they do it is they essentially give you a language that makes it very easy to generate such five pages, which together form the animation. If you look at this part here, this part here, and this part here, this is one part of the animation. As you go from one page to the next, the text disappears and a new one shows up. And here is how this language looks like. If you look at the program, this is nothing more than making a call to a special Ruby procedure. So slide exclamation mark is nothing but a Ruby function, Ruby procedure. And what follows on the slide is a function call to that procedure. And so what do you do first? The first argument is the title. Then the extra arguments are strings separated by comma because these are three extra arguments and these are the strings that will appear on the slide. And now we need to figure out a way of how to animate the other things. Well, so what do we do? But first let me show you how they do this cross thing, 0 equals 1 crossed with red. So they have a new function here called overlay, which takes this string and this red color and puts them on top of each other. And this becomes the fifth argument of that slide and shows up on the slide. Now we have a special function staggered overlay, which does what? It shows these text one after another on a page click or on a mouse click. Essentially it takes this, this, and this, and puts them on three separate pages one after another. Here is some extra information on where it should be located on the slide. And here is another staggered overlay for another animation. Here the call to this procedure ends. So here are the arguments to this procedure. And here is the extra thing that we add, which we don't need to talk about today. But what's inside the procedure already gives us a hint of how you implement these various small languages for programmers like those who want to create slides. So do you see any special tricks in addition to the one that you talked about? Just call a function with many arguments. The function accepts many arguments. And then in the body of this function slide, there is the semantics of what these arguments mean and how to generate the resulting figures. So if you look at how the code looks like, it's an ordinary functional language with strings and function calls. But they are organized in such a way that they form a reasonably easy to use language. So in a few parts of this code, there is the same pattern again and again, which we'll use as well. So what do you think is going on here and then again here? So what do you think is the dot pattern there? So this hedge is probably an object that is somewhere sitting in the library. And it probably means a line of some sort. And you're accessing its method called color, which sets the color of that line in that point of the slide. But you need to do it again and again, set its additional attributes. And so the result of this call here is again an object that is a visual object, and you can set its thickness. And you could continue additional calls of that sort on that object, and it would set other attributes such as the height. So what you see here is a common pattern for setting attributes without creating a text configuration file. And that thing is called call chaining. You just chain a bunch of calls. And it's easy with this pattern to forget that these are actually function calls, because they all of a sudden look like you are taking the hedge object and configuring it. And so you're using the function calls to actually implement the semantics. But it really looks like a nice configuration file. You forget the fact how the implementation happened. So additional small languages that one can build is Protoviz, a nice DSL for creating data visualization graphs, those that you cannot get in something like PowerPoint, various radial graphs, and stacked bars that you can configure freely. A student, Bill McCloskey, from Berkeley built his own very simple version of Make, which tracks dependencies between files, how they need to be compiled, and recompiling only those that have changed. Ruby on Rails, most of you know it's another system that builds on Ruby, essentially a language for building database-based websites. And then there is a bunch of custom scripting languages that people built to automate testing, to generate code for hardware. And many of them you will discover yourself as you work on your final project. Because the final project in the last three weeks of the semester is for you to invent a tiny language, design it, implement it, and show off with a demo at the end of the course. And of course there is the benefit of the course of just choosing the right language for the job, and saving maybe 10x or more in lines of code, because you pick something that fits the task really well. So if you look at all these languages that we've seen, people who create these languages are sort of a special kind of a programmer, right? What distinguishes them from the sort of normal kinds of programmers who build apps? So the answer is that they build tools for narrow domains, right? They build domain-specific languages. But just the fact that they build these languages is a different kind of programming than when I tell you build a web server, or build an application of a particular kind, right? So it is the fact that you are building tools for others that sort of differentiates the kind of the job that you do. So you are not the boilerplate programmer who just cuts and pays the code again and again, but really think about what tools other need. And you build those tools in the form of small languages for them. And so these tools for them could come in the form of libraries, which offer nice abstractions, frameworks, co-generators, small languages, and some of them end up defining big languages as well. So we saw about 10 concrete examples. And why this is important, you could look at what happened with other industries and chances are it will happen eventually with the software industry is that you look at textile and steel industry, at some point you would rather be making the machines for the textile industry than operating those machines. Because the job of operating those machines was not glamorous and eventually ended up overseas. And you can see the same thing in software industry as well. So you want to design those things for others to use. So this class is different because even though they tell you it's a compiler class, it's not really a compiler class. We build a small, simple compilers, but not a compiler for something like a subset of Java or Python. But instead, small compilers that you could then take as patterns and build in your programming practice. So it's about foundation of programming languages, because you'll need that to build those things. But also how to design your own languages, how to implement them, about PL tools, how debuggers, and of course about classical CS algorithms like parsing, data log, because this is part of programming languages as well. So we'll take a five minute break at this point. But it's not really a break, actually. So you'll have to talk to your neighbor and solve a puzzle. And then we look at the solution to the puzzle and solve it with a particular programming language. But it's better for you to solve it first by just discussing it, your own actual deduction. So the discussion is quietly coming to an end. So I'll stop it here. But I want to say a meta point is that get used to talking to each other, because we'll do this peer-based instruction where you try to explain things to each other and convince the other of your answer more often. So we'll do more of that. But I'll stop here, since it looks like most of you who wanted to come up with a solution, got a solution. So can any of these stamps be determined, A, B, or C? Somebody has an answer. Who thinks that none of them can be determined? Who thinks that some of them can be determined? So which one can be determined? It's OK. Clearly, it's OK to be wrong, right? We are learning here. They're all green. They're all green. Yellow, yellow, red. OK. So it's not as easy, apparently. Now, I'll show you the solution. You are supposed to read it at home. But what is the general approach for solving these kinds of puzzles? Is there like a formula that you can plug in and get the root of the polynomial? Right, so you were essentially enumerating the space of possibilities, right? There are seven stamps. They can end up on their heads in some possible ways. And now you ask, is this possible? Is this possible? And now, eventually, you want to rule out those that are not and say, oh, I see, given those that are possible, I see that this guy is green, right? And indeed, this is what the answer says. And I agree. It's not easy. And I didn't solve it myself, not because it's so hard, but because at some point you run out of steam and say, OK, I believe a computer could do it. Because there is really no smarts in it. I think this answer is written nicely. Rather than enumerating all of them, it does some sort of intelligent pruning. And it quickly throws out possibilities. But ultimately, this is a search as well, even in this answer. Now, if you believe that a computer can do it, we somehow need to convey these constraints given in the statement to the computer. And then computer can do its job. And how you choose to tell it to the computer is the question of what programming language you choose, or a library with some abstractions. Is it really about the abstractions that construct used to communicate this? So we look at the prologue language, which is an example of a language that's thought-shapery. It really forces you to think in a particular way. And sometimes that fits the problem really well and makes the program really concise. So it's a famous epigram from Ellen Pearl, who's one of the giants of computer science, that a language that doesn't affect the way you think is not worth learning. And in fact, all languages that you learned so far had some way of thinking. Scheme would be functional, and would make you think in terms of function, composition of functions using high-order operator like map and fold. Object-oriented made you think of the heap of objects and inheritance in them. And C would make you think, I don't know. Get me out of here kind of thing, right? So prologue is one such thought-shaper. And I'll try to walk you slowly through the solution to this puzzle in prologue. And we later program in it and implement it and do stuff on top of prologue, because it's a useful declarative constraints of the language. But let's walk through this. You get a flavor of what we do in programming languages. Find new ways of thinking about it and teaching the computers to represent it. So we have seven stamps, and we give them numbers 1, 2, 7. That's an easy decision. Could be 0 to 6, but we'll stick with 1 to 7. We need to say which of these stamps are what color. And so 1 and 2 will be red, 3 and 4 will be yellow. And we'll write them like this. Essentially, what these facts here state, they state that 1 is red, 2 is red, 3 is yellow. So now if I ask the system a question, what answer will I get? Well, either yes, no, or I don't know. So what do you think is the answer? The answer is no, right? Because the system considers this to be the complete set of facts. There are no other facts here that could come later. This is a closed world of facts. So the answer is no. Now if I ask yellow for, the answer is obviously yes. Now if I ask green, and I put here a variable x, what answer do you think I'll get from the system? I get the yes, because indeed one can find values for x that make it yes. So yes is part of the answer, but it will also give me essentially the list of values that make it yes. All right? This is logic programming that you did a little bit in 61A. So these are the facts. Essentially, we give stamps numbers and tell what color they have. So far, so good. Now we want to say, what is a stamp? This is easy. We are essentially saying that a stamp is either a red stamp or yellow stamp or a green stamp. What does this mean? Don't get alarmed. This simply means or, and this means an implication in this direction. If a stamp is red, or yellow, or green, it's a stamp. So when I say, when I ask the question stamp to, this is the prompt, what answer will I get? Absolutely yes. And if I ask stamp, say why, what answer will I get? Yes, and why can take what values? All of them, right? 1, 2, 7. So essentially, we have defined here, what? A domain of stamp, sort of a stamp data type. These are the things 1, 2, 7. OK, so far, so good. All right. So, oh, damn. OK. I don't want to erase it, but I guess I'll erase it. So now we say, what is a valid assignment of stamps on the heads, right? What is valid? Would 1, 1, 1 be a valid assignment? No, because the stamp can only end up on one head. So when I say valid, if I put a stamp here and a stamp here and a stamp there, it must be a stamp. So I'm essentially checking whether they have values 1, 2, 7 in here. This, by the way, ends, right? These were or, and this again is that. And here says that if A and B are different, and B and C are different, and A and C are different, it's a valid assignment. That's all I'm saying, OK? So valid 1, 1, 2 answers to what? No, and if I just ask for a valid assignment, I say A, B, and C, what do I get? I get the S, and then I get something like, oops, all right. Maybe A is 1, B is 2, and C is 3, and so on and so on. There are many more possibilities, right? 7 factorial to be precise, OK? So so far we know what's a valid assignment. OK, now the interesting stuff. Here we want to encode the fact that logician A, when he sees colors of B and C, he does his thinking or her thinking and says, no, I can't rule out any color. I could be yellow, I could be green, I could be red. All of them are possible given the colors I see. Now we don't know what these colors are, but we know that given the color you can see, none of them can be ruled out. So how do we state it here? How would you state it? Don't worry about the syntax. How would you write down the rules? Well, B and C can both be red, but in principle, they could be both red. Oh, I see. So you are right, but you are already using your human deduction, right? You are saying, I know there are two reds, and if the guy saw that there are both red, he would be able to conclude that, oh, I can rule out one of the colors. We don't want to do any of that reasoning. We just really want to plainly state the facts, or state to the base principles as much as please. That's right. It couldn't be any of the three colors. So this is essentially what we have. So we write so-called predicate. You can think of it as a function, if you want, called A-observe. So A is the logician A. He observes colors B and C. And what he says is that I can see B and C. And I'm now asking, remember, these are ends. Given the B and C I can see, does there exist a stamp that is red that would be a valid assignment together with the given B and C? And at the same time, does there exist a yellow that would be a valid assignment given B and C I can see? And at the same time, there must be a green that is a valid assignment with B and C. So this function is true if all of these six things hold because if there exists red, any yellow, and green, then he cannot rule out anything. So I have something in more detail to explain what it means. So how to read this rule? Imagine that the logician C is the two stamps and they are three and six. So yellow and green, I believe. But colors are not important. And now this B and C has become here, three and six over here. So they are bound. You could say that the variables are bound to values. And now you can see what we are really asking the system. Does there exist an R that gives you a valid assignment with three and six? And does there exist a Y? And does there exist a G? So the system looks for R, Y, and G that gives you the valid assignments. If it can find it, this is true. Otherwise, this is false. If this is false, means given these colors, he could actually rule out one of them. So you can think of it as we supply the colors that he can see. And he will ask, can I find matching stamps of any color? These questions. All right, so now we do something similar for the logician B. And she has a little bit harder task because she observes A and C, obviously, because she's a B. And she needs to find a matching R that goes with A and C, matching Y, Y that goes with A and C, and G to go here, right? OK. But we need to put this extra thing. What is that? So three extra conjuncts that we had to put in. Three extra rules. Exactly. So she does exactly the same reasoning as before, but has the extra condition that when the system finds an R that is a valid extension of A and C into a valid assignment, it must be such an R that together with the C, A would not have been able to conclude, oh, I cannot exclude that color. I cannot rule it out. So essentially, this part here tells us, looks at the reasoning that A would have done and takes its results here. Now finally, what is the solution? The solution is assignment of stamps to the system. And we say, well, find some stamp A and stamp B and stamp C such that when A observes B and C, he says, I cannot rule out any color. And when B observes A and C, she cannot rule out any color. So now we can ask the system this question. Is there a solution for A, B, and C that is valid? And the system says, yes, sure. There is one. And says, one, two, and five would be one valid solution, which is, I believe, red, red, and green. So how would we now ask the real question that the puzzle asked? We clearly can get a solution. We could enumerate all solutions. In fact, the system would do it for us. And we could enumerate all of them, look at them, and ask somehow, what would we ask? So can we do things without enumeration in some intelligent way? OK, excellent. So the suggestion is, rather than asking, is there a solution where A is anything, B is anything, and C is anything, instead we'll say, make this green, make this a specific color. How do we do it? We actually do it this way. We'll say, give me a solution such that the C that you find is a red. Could be one or two, but must be a red. This is exactly what you said, but it needs to be encoded that way, because you cannot pick one or two. You want to say it's either one or two. And when the answer is no, it means it could not find a solution where the C would have a red stamp. Means that one doesn't exist. Means you can rule it out. And if you can rule out both red and yellow, then you can determine the color of C, right? C must be green. C cannot be red or yellow because the answers here are no. So we have written a system where the rules were set down and the system would enumerate all the possibilities for us. And then we can ask this convenient question, give me all solutions, give me a solution with C being red. When the answer is no, we are happy that somebody did the deduction for us. So the summary is that, yes, we were forced to think differently, right? We were forced to create some sort of facts, stamps 1 to 7, give them colors, and then write the various rules. But once you get the hang of it, these puzzles are relatively easy to encode. And you will do them for homework. But not only that, we'll show you how to write a system that will take a simple natural language, not as free as from that book, but somewhat structured and translated automatically into a prologue program like this, sort of a puzzle solver. So we won't have to write it by hand, but the system will read in the natural language and spit out prologue program. Essentially, it will compile the natural language into prologue and solve a puzzle like this. So another part of today's lecture is about programming abstractions. Program abstractions are the things that make programming languages. So can some of you give me examples of programming abstractions? Functions are abstractions. Why are they called abstractions? What do they abstract away? In other words, what do they hide? Between the input values and the output values. So they hide the transformation, but really they hide the implementation of the transformation. The transformation itself, you may want to keep in mind. If you have a function that computes the power of a number, it does the transformation. You don't really care how it's implemented, whether it's fast and parallel or slow. But the transformation, the actual mathematical function, you still keep in mind. But the functions, the programming functions, abstract the way they hide the implementation. Once you write a function, you debug it, you can forget about it. What are those objects? So what do objects abstract away from? The abstract of implementation of the state of behavior, some of the state and behavior you expose in terms of methods of the objects and the state. Some other abstractions. Why are variables abstractions? Perfect. Oh, very good. What else? Overloading functions. So you are hiding the fact with overloading that there are really different implementations. They are called depending on, presumably, the types of arguments, right? But you don't care about the fact that there are many functions because the compiler or the runtime selects the right function for you. You don't care about the fact that there are many functions because the compiler or the runtime selects the right function for you. OK. Programming language itself is an abstraction. OK. You're not writing binary. Oh, I see. You mean the text of the programming language. So you could say the string, I should say, right? I would say the language is sort of the set of concepts, like data types and operations on them. But the text, OK, so strings are because you don't even know whether it's ASCII or Unicode. Mostly it's abstracted away from you. Excellent. Process would be an abstraction, yeah, because you don't really... Uh-huh, uh-huh, OK. You don't need to allocate memory. It all happens. You often have the illusion of there is infinite memory and you can start infinitely many processes. And it's not quite a true abstraction. It's easy to abuse it and bring the system to a grinding hold, OK? So this is good. So let me tell you how these abstractions actually evolved because it's an interesting story. Here is the first computer. That people built. And it's a true picture. It was programmed like this. You see some of sort of boilerplate problems that the people had to face when programming this computer. What would become annoying really quickly? By the way, they were all really proud to program it because it was a system that enabled you to do what you couldn't do before. You know, computed ballistic curves and, you know, hit the enemy just right. It was all war times after all. So what would become really annoying and how would you solve it? No VIM. Oh, it was a while before VIM. Eventually VIM arrived, but not yet. So if you look at this thing and read it carefully, it was not really a program. You sort of see a function table here and master programmer, accumulator, argument accumulator, accumulator, accumulator, functional unit. Those people actually built essentially circuits with these wires, essentially hooked up functional unit for multiplication and addition together into a circuit. Okay? So how would you deal with the problems here? What do you think was the next step? You may consider it for granted what the next step was, but this is really what started computer science is this is just wiring circuits, you could say. Okay, so you would use control signals. Where would you store those control signals? Punch cards, okay? You laugh, but the next big step was actually a tremendously big idea rather than building the program by wiring things. Works for musicians apparently, but you say we'll store it in memory. The punch cards are of course a memory. It's a read-only memory, but it's a memory nonetheless. And then you read the instructions from the memory from punch cards from tape and rather than wiring it up, you read the instructions, you wire it up before the execution of the instructions, you execute the instruction, you do the next one. Essentially you revire things before every instructions and the instructions are stored in memory. It's a big deal. So you could say the idea of program memory sort of abstracts away from the fact that things are wired up in the computer. And this is indeed what your processors do and you don't think about them as reviring things inside each time you execute an instruction, but the program memory idea abstracted away from that. Okay. What do you think became bothersome really quickly with the von Neumann program in memory computer? Clearly that was not the last abstraction I ever invented. Loading of the program in memory was a problem and punch cards, yeah a problem, believe it or not I still wrote a punch card program in my life. Of course I was behind the iron curtain so there were reasons for that, but that wasn't solved for a long time. But there was a problem that was solved that was really burning. It was solved probably right next after that. Debugging was a pain indeed and what people invented to simplify debugging. Yes, so there were many other abstractions that were appearing, but who can think what came next. So I'm not just trying to sort of teach you a history lesson while I do, I want you to start thinking about what is really painful here and how could I abstract it and encapsulate it, make it more usable. Because after all on the first homework you'll implement a nice web mashup and we'll ask you as part of the homework well what was painful and how would you fix it. So let's get some practice here. So what do you think was painful here? You couldn't modify the program. Okay, so the second half you couldn't reuse easily a program. Indeed there were no procedures in those early days. And so Morris Wilkes realized that the rest of his life he would be just debugging the programs because there are no procedures. He couldn't write a procedure and call it again. He was just writing these huge straight-light programs. It's hard to believe today, but indeed they were writing these big programs. There was no way to call to something that you have debugged. The idea of a library didn't exist. Library of functions, can you believe it? So procedures were invented around then, 51, 60 years ago, right? Clearly extremely important because now you could reuse code still written by hand, but you could reuse it. Okay. So then the next thing was machine code was extremely painful to write because it didn't have the notion of a variable like you said, variable abstracts away from the location. And indeed before this symbolic assembler you did not have a B or a C. What B or C? There was a physical number for an address. The B existed maybe in your head but not in the program. But with a symbolic assembler you could abstract away from that as well. And that was translated to what was the machine code of the time. So then people started writing essentially something like this MIPS symbolic assembly where you do have register names and you have CD array. You can use those that you can invent. You can use them to forget the fact that they are somewhere in memory. What was painful at this point? Writing loops like this, well, it was, okay, but how would you fix writing loops? What is problematic about this loop? If you write a loop, what sort of details visible here you could hide away? I couldn't hear. So they are retrieving the counter from memory. Yeah, that could be optimized but I would say that's not quite so easy to do all the time. But this code, if you think of loops of today, which of the details visible here you would hide? The name of the loop, like the fact that this is a label actually and you need to show where you need to jump, there is an explicit jump. If you compare it with the loops in Python where it doesn't even look like a loop but it's a map, it's a big deal. Essentially, things started going high level from here. Constructs for loops, the first interpreter code, speed coding, which was a really high level language, too slow for computers of those times, but nonetheless the first high level sort of scripting language. Then the real breakthrough came in Fortran in 54-57 where people figured out how to write compilers and translate from mathematically looking formulas that operated over a race, over actually machine code that was as good as Henry did. People never would believe that you can write a tool that translates from mathematically looking formula to machine code, but in a few years most people were using Fortran rather than assembly. Then Fortran is still sort of strange. The way it writes loops is that you put 10 here and this 10 refers to this and you end the loop by referring to this 10. So the syntax of Fortran was strange but it's still better than the low level code. So this is how loops looked in Fortran. But now Fortran had some funny problems that is good to look at because we want to learn from all mistakes. So can you look at this line and see what the bug might be? You might be able to guess what is wrong there. So I guess it doesn't have type. So what is this remember? So do 15 means do a loop that ends at the line marked with 15 and iterate from 1 to 100. But it doesn't quite say 1 to 100 what does it say? It says 1 to 1.1. Whereas what they intended was 1,100 which are two numbers. Now Fortran ignores spaces so great idea apparently. So this line is actually interpreted by the compiler as do15i which is a name of a variable into which you want to assign 1.1. So all of a sudden the loop looks like a declaration of a new variable into which you're assigning rather than a loop. It was hard to spot the difference between a comma and a dot because you can imagine the printers of the times. It was one of those old typewriter like printers. Hard to see whether it's a comma or not if the tape was old. And so this seems like oh it's a silly mistake, but this mistake I believe caused some space rocket was lost because of this mistake. So the loop just didn't execute when it came to it, just ran through with this assignment and some planetary probe was lost. So we have gone a long way and learned from mistakes like this and even C already came with better results. So a little bit more about loops. Here is an example of how object oriented programming came to be, but it's not as important. Oops. So you see a trend, right? In how we go from wiring to names of variables to loops to objects and so on. And so where do you think this abstraction trend will take us? Clearly we'll always have programs large enough to hide some plumbing and build new abstractions on top of it. Will it ever stop? Is there a chance it will stop? And where do you think these new abstractions will come from? Can you speak louder? So we'll teach them human speech, you could say well the human sort of the speech recognition is one part, right? But then still it's turned into a text and the text needs to be turned into a program. And of course arbitrary human text we will never be able to turn into somehow narrow down the domain of what you are able to say for the computer to still understand you. So we are on the right path something but the fact that we are speaking rather than typing, that itself is not as profound as the fact that in order to raise the level of abstraction we'll probably need to narrow down the domain in which we are speaking. You could say that in programming languages themselves many of the things that allow you to write a high level narrative, constraints, functions, objects, ways of composing things and people will improve it but if you look at where new abstractions are coming, they are coming from narrowing domains. You pick a target customers like your musicians and say what do these people want? What language do they speak? What abstractions? What concepts do they use in their language? These become the concepts in the programming language that you create for them, for physicists, for chemists, for economists. The concepts are that as we raise the level of abstraction it will come more and more from domains for narrowing users. It's all about creating new domain specific languages called small languages for those people. So new languages will be coming so just quickly how many languages have you already used? So don't give me examples of Java and C++ but something more esoteric that still is a language and you had to use it in your programming but people may not think of it as a language. Perfect. I was hoping that this is the first. Some people will tell you CSS is not really a language because it's more about the data organization of the tree and how you lay it out on the screen but clearly it is a language. You can format tree, CSS and code some semantics of how it appears on the screen when it's laid out. Excellent. Other non-obvious languages. Perfect. Database query language. MATLAB absolutely counts. Does it have data types? Can you specify computations with it? It's not even a data sort of language. It's a real computation language. Storing complete after all. Latex I would say put it next to CSS. It's a language in which you can specify documents. Probably cannot do computation. With latex you can. Macros, yes, you can do everything with latex. More. Absolutely. Shell scripts. Fantastic. I was hoping for that. Make tools for compilation and tracking dependencies. I would put it to data but not layout since it's more general. It's essentially a tree language for stating three types. Yes, it's sort of a MATLAB probably language. Right? Kind of essentially exposes mathematics and somewhat more software queries. And so more of these languages will come. And now look at the trend here. And what do you see? How often do languages appear? 10 years, 12 years or so. So are we overdue for a language? Or is it already here? You could say that Python is used much more but I would say that if you look at one language that is used on every device in JavaScript. Right? And you could say that it's just the assembly language of the web because many languages are built on top of it but that's really the future. Within which you can build other languages. Sort of metaprogramming style. And so if you look at these languages you realize that they were developed by people like you in the garage and you will develop some too. Maybe not these big languages I'll talk about this next time but I want to tell you about the project that is ahead of you. So the survivors of the last instance of the course got a t-shirt at the end and there are nine weekly assignments one of them essentially building interpreters and abstraction on top of it you can then build a parser and learn how to build compilers with it. And then there is a part where you build with scripting a little jQuery in it and Dataflow language. So first an interpreter in the first week then full coroutines to do fantastic iterators and on top of those you build a prolog interpreter. So stacking abstractions on top of each other. Then early parser will show you how it actually derives from a language called Datalog. You'll write a compiler and a Google calculator. The red backslash is there because you will remember it forever. There are different from each other. Can you tell how? Not in color of course but one is a division and the other one puts two units together and they have different precedents and getting the grammar right for this you'll have fun. So here is a layout engine scripting with jQuery, a baby jQuery and Dataflow in there and there is a contest in the end so the winners of sort of the best fastest parser on a project after the browser is done you want to implement a small language too show yourself that you can do it in two weeks could build on the browser could be something separate and so I'll just let you read this I don't want to I don't want to read the negative part okay so Thursday is no laptops every Thursdays we'll go back to basics without laptops so that you can talk more or less like today which is great today is the first homework you'll write the small mashups in javascript in the DOM essentially go to lastfm.com and you'll make the page make a query into all artists or something some database of artists and fetch an album of the artist that is being played in lastfm and displayed on the lastfm page can be done in a few lines of code but you'll learn a lot of languages and tools and you'll have to tell us what's broken about how it's implemented and how you imagine a good tool to do here is a calendar which you can find on the web some more details that I post on the web and piazza will be where we'll talk about projects and clarifications if you're on the waiting list I cannot really help you the class is full Michael David will be the one who can do something maybe you want to register for a different sections and then you'll get in and obvious thank you guys