Subtitles section Play video Print subtitles PROFESSOR: Well, now that we've given you some power to make independent local state and to model objects, I thought we'd do a bit of programming of a very complicated kind, just to illustrate what you can do with this sort of thing. I suppose, as I said, we were motivated by physical systems and the ways we like to think about physical systems, which is that there are these things that the world is made out of. And each of these things has particular independent local state, and therefore it is a thing. That's what makes it a thing. And then we're going to say that in the model in the world--we have a world and a model in our minds and in the computer of that world. And what I want to make is a correspondence between the objects in the world and the objects in the computer, the relationships between the objects in the world and the relationships between those same obj...--the model objects in the computer, and the functions that relate things in the world to the functions that relate things in the computer. This buys us modularity. If we really believe the world is like that, that it's made out of these little pieces, and of course we could arrange our world to be like that, we could only model those things that are like that, then we can inherit the modularity in the world into our programming. That's why we would invent some of this object-oriented programming. Well, let's take the best kind of objects I know. They're completely--they're completely wonderful: electrical systems. Electrical systems really are the physicist's best, best objects. You see over here I have some piece of machinery. Right here's a piece of machinery. And it's got an electrical wire connecting one part of the machinery with another part of the machinery. And one of the wonderful properties of the electrical world is that I can say this is an object, and this is an object, and they're-- the connection between them is clear. In principle, there is no connection that I didn't describe with these wires. Let's say if I have light bulbs, a light bulb and a power supply that's plugged into the outlet. Then the connection is perfectly clear. There's no other connections that we know of. If I were to tie a knot in the wire that connects the light bulb to the power supply, the light remains lit up. It doesn't care. That the way the physics is arranged is such that the connection can be made abstract, at least for low frequencies and things like that. So in fact, we have captured all of the connections there really are. Well, as you can go one step further and talk about the most abstract types of electrical systems we have, digital to dual circuits. And here there are certain kinds of objects. For example, in digital circuits we have things like inverters. We have things like and-gates. We have things like or-gates. We connect them together by sort-of wires which represent abstract signals. We don't really care as physical variables whether these are voltages or currents or some combination or anything like that, or water, water pressure. These abstract variables represent certain signals. And we build systems by wiring these things together with wires. So today what I'm going to show you, right now, we're going to build up an invented language in Lisp, embedded in the same sense that Henderson's picture language was embedded, which is not the same sense as the language of pattern match and substitution was done yesterday. The pattern match/substitution language was interpreted by a Lisp program. But the embedding of Henderson's program is that we just build up more and more procedures that encapsulate the structure we want. So for example here, I'm going to have some various primitive kinds of objects, as you see, that one and that one. I'm going to use wires to combine them. The way I represent attaching-- I can make wires. So let's say A is a wire. And B is a wire. And C is a wire. And D is a wire. And E is wire. And S is a wire. Well, an or-gate that has both inputs, the inputs being A and B, and the output being Y or D, you notate like this. An and-gate, which has inputs A and B and output C, we notate like that. By making such a sequence of declarations, like this, I can wire together an arbitrary circuit. So I've just told you a set of primitives and means of combination for building digital circuits, when I need more in a real language than abstraction. And so for example, here I have--here I have a half adder. It's something you all know if you've done any digital design. It's used for adding numbers together on A and B and putting out a sum and a carry. And in fact, the wiring diagram is exactly what I told you. A half adder with things that come out of the box-- you see the box, the boundary, the abstraction is always a box. And there are things that come out of it, A, B, S, and C. Those are the declared variables--declared variables of a lambda expression, which is the one that defines half adder. And internal to that, I make up some more wires, D and E, which I'm going to use for the interconnect-- here E is this one and D is this wire, the interconnect that doesn't come through the walls of the box-- and wire things together as you just saw. And the nice thing about this that I've just shown you is this language is hierarchical in the right way. If a language isn't hierarchical in the right way, if it turns out that a compound object doesn't look like a primitive, there's something wrong with the language-- at least the way I feel about that. So here we have--here, instead of starting with mathematical functions, or things that compute mathematical functions, which is what we've been doing up until now, instead of starting with things that look like mathematical functions, or compute such things, we are starting with things that are electrical objects and we build up more electrical objects. And the glue we're using is basically the Lisp structure: lambdas. Lambda is the ultimate glue, if you will. And of course, half adder itself can be used in a more complicated abstraction called a full adder, which in fact involves two half adders, as you see here, hooked together with some extra wires, that you see here, S, C1, and C2, and an or-gate, to manufacture a full adder, which takes a input number, another input number, a carry in, and produces output, a sum and a carry out. And out of full adders, you can make real adder chains and big adders. So we have here a language so far that has primitives, means of combination, and means of abstraction to real language. Now, how are we going to implement this? Well, let's do it easily. Let's look at the primitives. The only problem is we have to implement the primitives. Nothing else has to be implemented, because we're picking up the means of combination and abstraction from Lisp, inheriting them in the embedding. OK, so let's look at a particular primitive. An inverter is a nice one. Now, inverter has two wires coming in, an in and an out. And somehow, it's going to have to know what to do when a signal comes in. So somehow it's going to have to tell its input wire-- and now we're going to talk about objects and we're going to see this in a little more detail soon-- but it's going to have to tell its input wire that when you change, tell me. So this object, the object which is the inverter has to tell the object which is the input wire, hi, my name is George. And my, my job is to do something with results when you change. So when you change, you get a change, tell me about it. Because I've got to do something with that.