Placeholder Image

字幕列表 影片播放

  • [MUSIC PLAYING]

  • PROFESSOR: Well, so far we've invented enough programming to

  • do some very complicated things.

  • And you surely learned a lot about

  • programming at this point.

  • You've learned almost all the most important tricks that

  • usually don't get taught to people until they have had a

  • lot of experience.

  • For example, data directed programming is a major trick,

  • and yesterday you also saw an interpreted language.

  • We did this all in a computer language, at this point, where

  • there was no assignment statement.

  • And presumably, for those of you who've seen your Basic or

  • Pascal or whatever, that's usually considered the most

  • important thing.

  • Well today, we're going to do some thing horrible.

  • We're going to add an assignment statement.

  • And since we can do all these wonderful things without it,

  • why should we add it?

  • An important thing to understand is that today we're

  • going to, first of all, have a rule, which is going to always

  • be obeyed, which is the only reason we ever add a feature

  • to our language is because there is a good reason.

  • And the good reason is going to boil down to the ability,

  • you now get an ability to break a problem into pieces

  • that are different sets of pieces then you could have

  • broken it down without that, give you another means of

  • decomposition.

  • However, let's just start.

  • Let me quick begin by reviewing the kind of language

  • that we have now.

  • We've been writing what's called functional programs.

  • And functional programs are a kind of encoding of

  • mathematical truths.

  • For example, when we look at the factorial procedure that

  • you see on the slide here, it's basically two clauses.

  • If n is one, the result is one, otherwise n times

  • factorial n minus one.

  • That's factorial of n.

  • Well, that is factorial of n.

  • And written down in some other obscure notation that you

  • might have learned in calculus classes, mathematical logic,

  • what you see there is if n equals one, for the result of

  • n factorial is one, otherwise, greater than one, n factorial

  • is n times n minus one factorial.

  • True statements, that's the kind of

  • language we've been using.

  • And whenever we have true statements of that sort, there

  • is a kind of, a way of understanding how they work

  • which is that such processes can be involved by

  • substitution.

  • And so we see on the second slide here, that the way we

  • understand the execution implied by those statements in

  • arranged in that order, is that you do successive

  • substitutions of arguments for formal parameters in the body

  • of a procedure.

  • This is basically a sequence of equalities.

  • Factorial four is four times factorial three.

  • That is four times three times factorial of two and so on.

  • We're always preserving truth.

  • Even though we're talking about true statements, there

  • might be more than one organization of these true

  • statements to describe the computation of a particular

  • function, the computation of the value of

  • a particular function.

  • So, for example, looking at the next one here.

  • Here is a way of looking at the sum of n and m.

  • And we did this one by a recursive process.

  • It's the increment of the sum of the decrement of n and m.

  • And, of course, there is some piece of mathematical logic

  • here that describes that.

  • It's the increment of the sum of the decrement of n and m,

  • just like that.

  • So there's nothing particularly magic about that.

  • And, of course, if we can also look at an iterative process

  • for the same, a program that evolves an iterative process,

  • for the same function.

  • These are two things that compute the same answer.

  • And we have equivalent mathematical truths that are

  • arranged there.

  • And just the way you arrange those truths determine the

  • particular process.

  • In the way choose and arrange them determines the process

  • that's evolved.

  • So we have the flexibility of talking about both the

  • function to be computed, and the method

  • by which it's computed.

  • So it's not clear we need more.

  • However, today I'm going to this awful thing.

  • I'm going to introduce this assignment operation.

  • Now, what is this?

  • Well, first of all, there is going to be another kind of

  • kind of statement, if you will, in a programming

  • language called Set!

  • Things that do things like assignment, I'm going to put

  • exclamation points after.

  • We'll talk about what that means in a second.

  • The exclamation point, again like question mark, is an

  • arbitrary thing we attach to the symbol which is the name,

  • has no significance to the system.

  • The only significance is to me and you to alert you that this

  • is an assignment of some sort.

  • But we're going to set a variable to a value.

  • And what that's going to mean is that there is a time at

  • which something happens.

  • Here's a time.

  • If I have time going this way, it's a time access.

  • Time progresses by walking down the page.

  • Then an assignment is the first thing we have that

  • produces the difference between a before and an after.

  • All the other programs that we've written, that have no

  • assignments in them, the order in which they were evaluated

  • didn't matter.

  • But assignment is special, it produces a moment in time.

  • So there is a moment before the set occurs and after, such

  • that after this moment in time, the variable has the

  • value, value.

  • Independent of what value it had before, set!

  • changes the value of the variable.

  • Until this moment, we had nothing that changed.

  • So, for example, one of the things we can think of is that

  • the procedures we write for something like factorial are

  • in fact pretty much identical to the function factorial.

  • Factorial of four, if I write fact4, independent of what

  • context it's in, and independent of how many times

  • I write it, I always get the same answer.

  • It's always 24.

  • It's a unique map from the argument to the answer.

  • And all the programs we've written so far are like that.

  • However, once I have assignment, that isn't true.

  • So, for example, if I were to define count to be one.

  • And then I'm going to define also a procedure, a simple

  • procedure called demo, which takes argument x and does the

  • following operations.

  • It first sets x to x plus one.

  • My gosh, this looks just like FORTRAN, right--

  • in a funny syntax.

  • And then add to x count, Oh, I just made a mistake.

  • I want to say, set! count to one plus count.

  • It's this thing defined here.

  • And then plus x count.

  • Then I can try this procedure.

  • Let's run it.

  • So, suppose I get a prompt and I say, demo three.

  • Well, what happens here?

  • The first thing that happens is count is currently one.

  • Currently, there is a time.

  • We're talking about time.

  • x gets three.

  • At this moment, I say, oh yes, count is

  • incremented, so count is two.

  • two plus three is five.

  • So the answer I get out is five.

  • Then I say, demo of say, three again.

  • What do I get?

  • Well, now count is two, it's not one anymore, because I

  • have incremented it.

  • But now I go through this process, three goes into x,

  • count becomes one plus count, so that's three now.

  • The sum of those two is six, so the answer is six.

  • And what we see is the same expression leads to two

  • different answers, depending upon time.

  • So demo is not a function, does not compute a

  • mathematical function.

  • In fact, you could also see why now, of course, this is

  • the first place where the substitution model

  • isn't going to work.

  • This kills the substitution model dead.

  • You know, with quotation there were some little problems that

  • a philosopher might notice with the substitutions,

  • because you have to worry about what deductions you can

  • make when you substitute into quotes, if you're allowed to

  • do that at all.

  • But here the substitution model is dead, can't do

  • anything at all.

  • Because, supposing I wanted to use a substitution model to

  • consider substituting for count?

  • Well, my gosh, if I substitute for here and here, they're

  • different ones.

  • It's not the same count any more.

  • I get the wrong answer.

  • The substitution model is a static phenomenon that

  • describes things that are true and not things that change.

  • Here, we have truths that change.

  • OK, Well, before I give you any understanding of this,

  • this is very bad.

  • Now, we've lost our model of computation.

  • Pretty soon, I'm going to have to build you a new model of

  • computation.

  • But ours plays with this, just now, in an informal sense.

  • Of course, what you already see is that when I have

  • something like assignment, the model that we're going to need

  • is different from the model that we had before in that the

  • variables, those symbols like count, or x are no longer

  • going to refer to the values they have, but rather to some

  • sort of place where the value restored.

  • We're going to have to think that way for a while.

  • And it's going to be a very bad thing and

  • cause a lot of trouble.

  • And so, as I said, the very fact that we're inventing this

  • bad thing, means that there had better be a good reason

  • for it, otherwise, just a waste of time

  • and a lot of effort.

  • Let's just look at some of it just to play.

  • Supposing we write down the functional version, functional

  • meaning in the old style, of factorial by

  • an iterative process.

  • Factorial of n, we're going to iterate of m and i, which says

  • if i is greater than n, then the result is m, otherwise,

  • the result of iterating the product of i and m.

  • So m is going to be the product that I'm accumulating.

  • m is the product.

  • And the count I'm going to increase by one.

  • Plus, ITER, ELSE, COND, define.

  • I'm going to start this up.

  • And these days, you should have no trouble reading

  • something like this.

  • What I have here is a product there being

  • accumulated and a counter.

  • I start them up both at one.

  • I'm going to buzz the counter up, i goes to i plus one every

  • time around.

  • But that's only our putting a time on the process, each of

  • this is just a set of truths, true rules.

  • And m is going to get a new values of i and m, i times m

  • each time around, and eventually i is going to be

  • bigger than n, in which case, the answer's going to be m.

  • Now, I'm speaking to you, use time in this.

  • That's just because I know how the computer works.

  • But I didn't have to.

  • This could be a purely mathematical description at

  • this point, because substitution

  • will work for this.

  • But let's set right down a similar sort of program, using

  • the same algorithm, but with assignments.

  • So this is called the functional version.

  • I want to write down an imperative version.

  • Factorial of n.

  • I'm going to create my two variables.

  • Let i initialize itself to one, and m be initialized to

  • one, similar.

  • We'll create a loop which has COND greater than i, and if i

  • is greater than n, we're done.

  • And the result is m, the product I'm accumulating.

  • Otherwise, I'm going to write down three things to do.

  • I'm going to set!

  • m to the product of i and m, set! i to the sum of i and

  • one, and go around the loop again.

  • Looks very familiar to you FORTRAN programmers.

  • ELSE, COND, define, funny syntax though.

  • Start the loop up, and that's the program.

  • Now, this program, how do we think about it?

  • Well, let's just say what we're seeing here.

  • There are two local variables, i and m, that have been

  • initialized to one.

  • Every time around the loop, I test to see if i is greater

  • than n, which is the input argument, and if so, the

  • result is the product being accumulated in m.

  • However, if it's not the end of the loop, if I'm not done,

  • then what I'm going to do is change the product to be the

  • result of multiplying i times the current product.

  • Which is sort of what we were doing here.

  • Except here I wasn't changing.

  • I was making another copy, because the substitution model

  • says, you copy the body of the procedure with the arguments

  • substituted for the formal parameters.

  • Here I'm not worried about copying, here I've changed the

  • value of m.

  • I also then change the value of i to i plus one, and go

  • buzzing around.

  • Seems like essentially the same program, but there are

  • some ways of making errors here that

  • didn't exist until today.

  • For example, if I were to do the horrible thing of not

  • being careful in writing my program and interchange those

  • two assignments, the program wouldn't

  • compute the same function.

  • I get a timing error because there's a dependency that m

  • depends upon having the last value of i.

  • If I try to i first, then I've got the wrong value of i when

  • I multiply by m.

  • It's a bug that wasn't available until this moment,

  • until we introduced something that had time in it.

  • So, as I said, first we need a new model of computation, and

  • second, we have to be damn good reason for doing this

  • kind of ugly thing.

  • Are there any questions?

  • Speak loudly, David.

  • AUDIENCE: I'm confused about, we've introduced set now, but

  • we had let before and define before.

  • I'm confused about the difference between the three.

  • Wouldn't define work in the same situation as set if you

  • introduced it a bit?

  • PROFESSOR: No, define is intended for setting something

  • once the first time, for making it.

  • You've never seen me write on a blackboard two defines in a

  • row whose intention was to change the old value of some

  • variable to a new one.

  • AUDIENCE: Is that by convention or--

  • PROFESSOR: No, it's intention.

  • The answer is that, for example, internal to a

  • procedure, two defines in a row are illegal, two defines

  • in a row of the same variable.

  • x can't be defined twice.

  • Whether or not a system catches that error is a

  • different question, but I legislate to you that define

  • happens once on anything.

  • Now, indeed, in interactive debugging, we intend that you

  • interacting with your computer will redefine things, and so

  • there's a special exception made

  • for interactive debugging.

  • But define is intended to mean to set up something which will

  • be forever that value after that point.

  • It's as if all the defines were done at the beginning.

  • In fact, the only legal place to put a define in Scheme,

  • internal to a procedure, is just at the beginning of a

  • lambda expression, the beginning of

  • the body of a procedure.

  • Now, let of course does nothing like either of that.

  • I mean, if you look at what's happening with a let, this

  • happens again exactly once.

  • It sets up a context where i and m are values one and one.

  • That context exists throughout this scope, this

  • region of the program.

  • However, you don't think of that let as setting i again.

  • It doesn't change it.

  • i never changes because of the let.

  • i gets created because of let.

  • In fact, the let is a very simple idea.

  • Let does nothing more, Let a variable one to have value

  • one; I'll write this down a little bit more neatly; Let's

  • write, var one have value, the value of expression e1, and

  • variable two, have this value of the expression e2, in an

  • expression e3, is the same thing as a procedure of var

  • one and var two, the formal parameters, and e3 being the

  • body, where var one is bound to the value of e1, and var

  • two gets the value of e2.

  • So this is, in fact, a perfectly understandable thing

  • from a substitution point of view.

  • This is really the same expression written in two

  • different ways.

  • In fact, the way the actual system works is this gets

  • translated into this before anything happens.

  • AUDIENCE: OK, I'm still unclear as then what makes the

  • difference between a let and a define.

  • They could--

  • PROFESSOR: A define is a syntactic sugar, whereby,

  • essentially a bunch of variables get created by lets

  • and then set up once.

  • OK, time for the first break, I think.

  • Thank you.

  • [MUSIC PLAYING]

  • Well let's see.

  • I now have to rebuild the model of computation, so you

  • understand how some such mechanical mechanism could

  • work that can do what we've just talked about.

  • I just recently destroyed your substitution model.

  • Unfortunately, this model is significantly more complicated

  • than the substitution model.

  • It's called the environment model.

  • And I'm going to have to introduce some terminology,

  • which is very good terminology for you to know anyway.

  • It's about names.

  • And we're going to give names to the kinds of names things

  • have and the way those names are used.

  • So this is a meta-description, if you will.

  • Anyway, there is a pile of an unfortunate terminology here,

  • but we're going to need this to understand what's called

  • the environment model.

  • We're about to do a little bit of boring, dog-work here.

  • Let's look at the first transparency.

  • And we see a description of a word called bound.

  • And we're going to say that a variable, v, is bound in an

  • expression, e, if the meaning of e is unchanged by the

  • uniform replacement of a variable w, not occurring in

  • e, for every occurrence of v in e.

  • Now that's a long sentence, so, I think, I'm going to have

  • to say a little bit about that before we even fool

  • around at all here.

  • Bound variables we're talking about here.

  • And you've seen lots of them.

  • You may not know that you've seen lots of them.

  • Well, I suppose in your logic you saw a logical variables

  • like, for every x there exists a y such that p is true of x

  • and y from your calculus class.

  • This variable, x, and this variable, y, are bound,

  • because the meaning of this expression does not depend

  • upon the particular letters I used to describe x and y.

  • If I were to change the w for x, then said for every w there

  • exists a y such that p is true of w and y, it would be the

  • same sentence.

  • That's what it means.

  • Or another case of this that you've seen is integral say,

  • from 0 to one of dx over one plus x square.

  • Well that's something you see all the time.

  • And this x is a bound variable.

  • If I change that to a t, the expression is

  • still the same thing.

  • This is a 1/4 of the arctan of one or something like that.

  • Yes, that's the arctan of one.

  • So bound variables are actually fairly common, for

  • those of you who have played a bit with mathematics.

  • Well, let's go into the programming world.

  • Instead of the quantifier being something like, for

  • every, or there exists, or integral, a quantifier is a

  • symbol that binds a variable.

  • And we are going to use the quantifier lambda as being the

  • essential thing that binds variables.

  • And so we have some nice examples here like that

  • procedure of one argument y which does

  • the following thing.

  • It calls the procedure of one argument x, which multiplies x

  • by y, and applies that to three.

  • That procedure has the property there of two bound

  • variables in it, x and y.

  • This quantifier, lambda here, binds this y, and this

  • quantifier, lambda, binds that x.

  • Because, if I were to take an arbitrary symbol does not

  • occur in this expression like w and replace all y's with w's

  • in this expression, the expression is still the same,

  • the same procedure.

  • And this is an important idea.

  • The reason why we had such things like that is a kind of

  • modularity.

  • If two people are writing programs, and they work

  • together, it shouldn't matter what names they use internal

  • to their own little machines that they're building.

  • And so, what I'm really telling you there, is that,

  • for example, this is equivalent to that procedure

  • of one argument y which uses that procedure of one argument

  • d which multiplies z by y.

  • Because nobody cares what I used in here.

  • It's a nice example.

  • On the other hand, I have some variables that are not bound.

  • For example, that procedure of one argument x which

  • multiplies x by y.

  • In this case, y is not bound.

  • Supposing y had the value three, and z had the value

  • four, then this procedure would be the thing that

  • multiplies its argument by three.

  • If I were to replace every instance of y with z, I would

  • have a different procedure which multiplies every

  • argument that's given by four.

  • And, in fact, we have a name for such a variable.

  • Here, we say that a variable, v, is free in the expression,

  • e, if the meaning of the expression, e, is changed by

  • the uniform replacement of a variable, w, not occurring in

  • e for every occurrence of v and e.

  • So that's why this variable over here,

  • y, is a free variable.

  • And so free variables in this expression--

  • And other examples of that is that procedure of one argument

  • y, which is just what we had before, which uses that

  • procedure of one argument x that multiplies x by y--

  • use that on three.

  • This procedure has a free variable

  • in it which is asterisk.

  • See, because, if that has a normal meaning of

  • multiplication, then if I were to replace uniformly all

  • asterisks with pluses, then the meaning of this expression

  • would change.

  • That's what you mean by a free variable.

  • So, so far you've learned some logician words which describe

  • the way names are used.

  • Now, we have to do a little bit more playing around here,

  • a little bit more.

  • I want to tell you about the regions are over which

  • variables are defined.

  • You see, we've been very informal about this up till

  • now, and, of course, many of you have probably understood

  • very clearly or most of you, that the x that's being

  • declared here is defined only in here.

  • This x is the defined only in here, and this y is defined

  • only in here.

  • We have a name for such an idea.

  • It's called a scope.

  • And let me give you another piece of terminology.

  • It's a long story.

  • If x is a bound variable in e, then there is a lambda

  • expression where it is bound.

  • So the only way you can get a bound variable ultimately is

  • by lambda expression.

  • Then you may worry, does define quite an

  • exception to this?

  • And it turns out, we could always arrange things so you

  • don't need any defines.

  • And we'll see that in a while.

  • It's a very magical thing.

  • So define really can go away.

  • The really, only thing that makes names is lambda .

  • That's its job.

  • And what's so amazing about a lot of things is you can

  • compute with only lambda.

  • But, in any case, a lambda expression has a place where

  • it declares a variable.

  • We call it the formal parameter list or the bound

  • variable list. We say that the lambda expression binds--

  • so it's a verb--

  • binds the variables declared in it's found variable list.

  • In addition, those parts of the expression where the

  • variable is defined, which was declared by some declaration,

  • is called the scope of that variable.

  • So these are scopes.

  • This is the scope of y.

  • And this is the scope of x--

  • that sort of thing.

  • OK, well, now we have enough terminology to begin to

  • understand how to make a new model for computation, because

  • the key thing going on here is that we destroyed the

  • substitution model, and we now have to have a model that

  • represents the names as referring to places.

  • Because if we are going to change something, then we have

  • a place where it's stored.

  • You see, if a name only refers to a value, and if I tried to

  • change the name's meaning, well, that's not clear.

  • There's nothing that is the place that that

  • name referred to.

  • How am I really saying it?

  • There is nothing shared among all of the

  • instances of that name.

  • And what we really mean, by a name, is that we

  • fan something out.

  • We've given something a name, and you have it, and you have

  • it, because I'm given you a reference to it, and I've

  • given you a reference to it.

  • And we'll see a lot about that.

  • So let me tell you about environments.

  • I need the overhead projection machine, thank you.

  • And so here is a bunch of environment structures.

  • An environment is a way of doing substitutions virtually.

  • It represents a place where something is stored which is

  • the substitutions that you haven't done.

  • It's a place where everything accumulates, where the names

  • of the variables are associated with the values

  • they have such that when you say, what dose this name mean,

  • you look it up in an environment.

  • So an environment is a function, or a table, or

  • something like that.

  • But it's a structured sort of table.

  • It's made out of things called frames.

  • Frames are pieces of environment, and they are

  • chained together, in some nice ways, by what's called parent

  • links or something like that.

  • So here, we have an environment structure

  • consisting of three environments,

  • basically, a, b, and c.

  • d is also an environment, but it's the same one, they share.

  • And that's the essence of assignment.

  • If I change a variable, a value of a valuable that lives

  • here, like that one, it should be visible from all places

  • that you're looking at it from.

  • Take this one, x.

  • If I change the x to four, it's

  • visible from other places.

  • But I'm not going to worry about that right now.

  • We're going to talk a lot about that in a little while.

  • What do we have here?

  • Well, these are called frames.

  • Here is a frame, here's a frame, and here's a frame.

  • a is an environment which consists of the table which is

  • frame two, followed by the table labeled frame one.

  • And, in this environment, in say this environment, frame

  • two, x and y are bound.

  • They have values.

  • Sorry, in frame one--

  • In frame two, z is bound, and x is bound, and y is bound,

  • but the value of x that we see, looking from this point

  • of view, is this x.

  • It's x is seven, rather than this one which is three.

  • We say that this x shadows this x.

  • From environment three--

  • from frame three, from environment b, which refers to

  • frame three, we have variables n and y bound and also x.

  • This y shadow this one.

  • So the value, looking from this point of

  • view, of y is two.

  • The value for looking from this point of

  • view and m is one.

  • And the value, looking from this point of

  • view, of x is three.

  • So there we have a very simple environment

  • structure made out of frames.

  • These correspond to the applications of procedures.

  • And we'll see that in a second.

  • So now I have to make you some other nice little structure

  • that we build.

  • Next slide, we see an object, which I'm going to draw

  • procedures.

  • This is a procedure.

  • A procedure is made out of two parts.

  • It's sort of like a cons.

  • However, it's the two parts.

  • The first part refers to some code, something that can be

  • executed, a set of instructions, if you will.

  • You can think of it that way.

  • And the second part is the environment.

  • The procedure is the whole thing.

  • And we're going to have to use this to capture the values of

  • the free variables that occur in the procedure.

  • If a variable occurs in the procedure it's either bound in

  • that procedure or free.

  • If it's bound, then the value will somehow be easy to find.

  • It will be in some easy environment to get at.

  • If it's free, we're going to have to have something that

  • goes with the procedure that says where we'll go

  • look for its value.

  • And the reasons why are not obvious yet, but will be soon.

  • So here's a procedure object.

  • It's a composite object consisting of a piece of code

  • and a environment structure.

  • Now I will tell you the new rules, the complete new rules,

  • for evaluation.

  • The first rule is-- there's only two of them.

  • These correspond to the substitution model rules.

  • And the first one has to do with how do you apply a

  • procedure to its arguments?

  • And a procedural object is applied to a set of arguments

  • by constructing a new frame.

  • That frame will contain the mapping of the former

  • parameters to the actual parameters of the arguments

  • that were supplied in the call.

  • As you know, when we make up a call to a procedure like

  • lambda x times x y, and we call that with the argument

  • three, then we're going to need some

  • mapping of x to three.

  • It's the same thing as later substituting, if you will, the

  • three for the x in the old model.

  • So I'm going to build a frame which contains x equals three

  • as the information in that frame.

  • Now, the body of the procedure will then have to be evaluated

  • which is this.

  • I will be evaluated in an environment which is

  • constructed by adjoining the new frame that we just made to

  • the environment which was part of the

  • procedure that we applied.

  • So I'm going to make a little example of that here.

  • Supposing I have some environment.

  • Here's a frame which represents it.

  • And some procedure-- which I'm going to draw with circles

  • here because it's easier than little triangles--

  • Sorry, those are rhombuses, rhomboidal little pieces of

  • fruit jelly or something.

  • So here's a procedure which takes this environment.

  • And the procedure has a piece of code, which is a lambda

  • expression, which binds x and y and then executes an

  • expression, e.

  • And this is the procedure.

  • We'll call it p.

  • I wish to apply that procedure to three and four.

  • So I want to do p of three and four.

  • What I'm going to do, of course, is make a new frame.

  • I build a frame which contains x equals three,

  • and y equals four.

  • I'm going to connect that frame to this frame over here.

  • And then this environment, with I will call b, is the

  • environment in which I will evaluate the body of e.

  • Now, e may contain references to x and y and other things.

  • x and y will have values right here.

  • Other things will have their values here.

  • How do we get this frame?

  • That we do by the construction of procedures which is the

  • other rule.

  • And I think that's the next slide.

  • Rule two, when a lambda expression is evaluated,

  • relative to a particular environment--

  • See, the way I get a procedure is by evaluating the lambda

  • expression.

  • Here's a lambda expression.

  • By evaluating it, I get a procedure which I

  • can apply to three.

  • Now this lambda expression is evaluated in an environment

  • where y is defined.

  • And I want the body of this which contains a

  • free version of y.

  • y is free in here, it's bound over the whole thing, but it's

  • free over here.

  • I want that y to be this one.

  • I evaluate this body of this procedure in the environment

  • where y was created.

  • That's this kind of thing, because that was done by

  • application.

  • Now, if I ever want to look up the value of y, I have to know

  • where it is.

  • Therefore, this procedural was created, the creation of the

  • procedure which is the result of evaluating that lambda

  • expression had better capture a pointer or remember the

  • frame in which y was bound.

  • So that's what this rule is telling us.

  • So, for example, if I happen to be evaluating a lambda

  • expression, lambda expression in e, lambda of say, x and y,

  • let's call it g in e, evaluating that.

  • Well, all that means is I now construct a procedure object.

  • e is some environment.

  • e is something which has a pointer to it.

  • I construct a procedure object that points up to that

  • environment, where the code of that is a lambda expression or

  • whatever that translates into.

  • And this is the procedure.

  • So this produces for me-- this object here, this environment

  • pointer, captures the place where this lambda expression

  • was evaluated, where the definition was used, where the

  • definition was used to make a

  • procedure, to make the procedure.

  • So it picks up the environment from the place where that

  • procedure was defined, stores it in the procedure itself,

  • and then when the procedure is used, the environment where it

  • was defined is extended with the new frame.

  • So this gives us a locus for putting where a

  • variable has a value.

  • And, for example, if there are lots of guys pointing in at

  • that environment, then they share that place.

  • And we'll see more of that shortly.

  • Well, now you have a new model for understanding the

  • execution of programs. I suppose I'll take questions

  • now, and then we'll go on and use that for something.

  • AUDIENCE: Is it right to say then, the environment is that

  • linked chain of frames--

  • PROFESSOR: That's right.

  • AUDIENCE: starting with--

  • working all the way back?

  • PROFESSOR: Yes, the environment is a sequence of

  • frames linked together.

  • And the way I like to think about it, it's the pointer to

  • the first one, because once you've got that

  • you've got them all.

  • Anybody else?

  • AUDIENCE: Is it possible to evaluate a procedure or to

  • define a procedure in two different environments such

  • that it will behave differently, and

  • have pointers to both--

  • PROFESSOR: Oh, yes.

  • The same procedure is not going to have two different

  • environments.

  • The same code, the same lambda expression can be evaluated in

  • two environments producing two different procedures.

  • Each procedure--

  • AUDIENCE: Their definition has the same name.

  • Their operation--

  • PROFESSOR: The definition is written the same, with the

  • same characters.

  • I can evaluate that set of characters, whatever, that

  • list structure that defines, that is the textual

  • representation.

  • I can evaluate that in two different environments

  • producing two different procedures.

  • Each of those procedures has its own local sets of

  • variables, and we'll see that right now.

  • Anybody else?

  • OK, thank you.

  • Let's take a break.

  • [MUSIC PLAYING]

  • Well, now I've done this terrible thing to you.

  • I've introduced a very complicated thing, assignment,

  • which destroys most of the interesting mathematical

  • properties of our programs. Why should I have done this?

  • What possible good could this do?

  • Clearly not a nice thing, so I better have a good excuse.

  • Well, let's do a little bit of playing, first of all, with

  • some very interesting programs that have assignment.

  • Understand something special about them that makes them

  • somewhat valuable.

  • Start with a very simple program which I'm going to

  • call make-counter.

  • I'm going to define make-counter to be a procedure

  • of one argument n which returns as its value a

  • procedure of no arguments--

  • a procedure that produces a procedure--

  • which sets n to the increment of n and returns

  • that value of n.

  • Now we're going to investigate the behavior of this.

  • It's a sort of interesting thing.

  • In order to investigate the behavior, I have to make an

  • environment model, because we can't understand

  • this any other way.

  • So let's just do that.

  • We start out with some sort of--

  • let's say there is a global environment that the machine

  • is born with.

  • Global we'll call it.

  • And it's going to have in it a bunch of initial things.

  • We all know what it's got.

  • It's got things in it like say, plus, and times, and

  • quotient, and difference, and CAR, and et

  • cetera, lots of things.

  • I don't know what they are, some various squiggles that

  • are the things the machine is born with.

  • And by doing the definition here, what I plan to do--

  • Well, what am I doing?

  • I'm doing this relative to the global environment.

  • So here's my environment pointer.

  • In order to do that I have to evaluate this lambda

  • expression.

  • That means I make a procedure object.

  • So I'm going to make a procedure object here.

  • And the procedure object has, as the place it's defined, the

  • global environment.

  • The procedure object contains some code that represents a

  • procedure of one argument n which returns a procedure of

  • no arguments which does something.

  • And the define is a way of changing this environment, so

  • that I now add to it a make-counter, a special rule

  • for the special thing defined.

  • But what that is, is it gives me that

  • pointer to that procedure.

  • So now the global environment contains make-counter as well.

  • Now, we're going to do some operations.

  • I'm going to use this to make some counters.

  • We'll see what a counter is.

  • So let's define c1 to be a counter beginning at 0.

  • Well, we know how to do this now, according to the model.

  • I have to evaluate the expression make-counter in the

  • global environment, make-counter of 0.

  • Well, I look up make-counter and see that it's a procedure.

  • I'm going to have to apply that procedure.

  • The way I apply the procedure is by constructing a frame.

  • So I construct a frame which has a value for n in it which

  • is 0, and the parent environment is the one which

  • is the environment of definition of make-counter.

  • So I've made an environment by applying make-counter to 0.

  • Now, I have to evaluate the body of make-counter, which is

  • this lambda expression, in that environment.

  • Well evaluating this body, this body is a lambda

  • expression.

  • Evaluate a lambda expression means make a procedure object.

  • So I'm going to make a procedure object.

  • And that procedure object has the environment it was defined

  • in being that, where n was defined to be 0.

  • And it has some code, which is the procedure of no arguments

  • which does something, that sets something, and returns n.

  • And this thing is going to be the object, which in the

  • global environment, will have the name c1.

  • So we construct a name here, c1, and say that equals that.

  • Now, but also make another counter, c2 to be make-counter

  • say, starting with 10.

  • Then I do essentially the same thing.

  • I apply the make-counter procedure, which I got from

  • here, to make another frame with n being 10.

  • That frame has the global environment as its parent.

  • I then construct a procedure which has that as it's frame

  • of definition.

  • The code of it is the procedure of no arguments

  • which does something.

  • And it does a set, and so on.

  • And n comes out.

  • And c2 is this.

  • Well, you're already beginning to see something fairly

  • interesting.

  • There are two n's here.

  • They are not one n.

  • Each time I called make-counter, I made another

  • instance of n.

  • These are distinct and separate from each other.

  • Now, let's do some execution, use those counters.

  • I'm going to use those counters.

  • Well, what happens if I say, c1 at this point?

  • Well, I go over here, and I say, oh

  • yes, c1 is a procedure.

  • I'm going to call this procedure on no arguments, but

  • it has no parameters.

  • That's right.

  • What's its body?

  • Well, I have to look over here, because I

  • didn't write it down.

  • It said, set n to one plus n and return n, increment n.

  • Well, the n it sees is this one.

  • So I increment that n.

  • That becomes one, and I return the value one.

  • Supposing I then called c2.

  • Well, what do I do?

  • I say c2 is this procedure which does the same thing, but

  • here's the n.

  • It becomes 11.

  • And so I have an 11 which is the value.

  • I then can say, let's try c1 again.

  • c1 is this, that's two, so the answer is two.

  • And c2 gives me a 12 by the same method, by walking down

  • here looking at that and saying, here's the n, I'm

  • incrementing.

  • So what I have are computational objects.

  • There are two counters, each with its own

  • independent local state.

  • Let's talk about this a little.

  • This is a strange thing.

  • What's an object?

  • It's not at all obvious what an object is.

  • We like to think about objects, because it's

  • economical to think that way.

  • It's an intellectual economy.

  • I am an object.

  • You are an object.

  • We are not the same object.

  • I can divide the world into two parts, me and you, and

  • there's other things as well, such that most of the things I

  • might want to discuss about my workings do not involve you,

  • and most of the things I want to discuss about your workings

  • don't involve me.

  • I have a blood pressure, a temperature, a respiration

  • rate, a certain amount of sugar in my blood, and

  • numerous, thousands, of state variables-- millions actually,

  • or I don't know how many--

  • huge numbers of state variables in the physical

  • sense which represent the state of me as a particle, and

  • you have gazillions of them as well.

  • And most of mine are uncoupled to most of yours.

  • So we can compute the properties of me without

  • worrying too much about the properties of you.

  • If we had to work about both of us together, than the

  • number of states that we have to consider is the product of

  • the number of states you have and the number of states I

  • have. But this way it's almost a sum.

  • Now, indeed there are forces that couple us.

  • I'm talking to you and your state changes.

  • I'm looking at you and my state changes.

  • Some of my state variables, a very few of them, therefore,

  • are coupled to yours.

  • If you were to suddenly yell very loud, my blood pressure

  • would go up.

  • However, and it may not be always appropriate to think

  • about the world as being made out of independent states and

  • independent particles.

  • Lots of the bugs that occur in things like quantum mechanics,

  • or the bugs in our minds that occur when we think about

  • things like quantum mechanics, are due the fact that we are

  • trying to think about things being broken up into

  • independent pieces, when in fact there's more coupling

  • than we see on the surface, or that we want to believe in,

  • because we want to compute efficiently and effectively.

  • We've been trained to think that way.

  • Well, let's see.

  • How would we know if we had objects at all?

  • How can we tell if we have objects?

  • Consider some possible optical illusions.

  • This could be done.

  • These pieces of chalk are not appropriately identical, but

  • supposing you couldn't tell the difference of them by

  • looking at them.

  • Well, there's a possibility that this all a game I'm

  • playing with mirrors.

  • It's really the same piece of chalk, but you're

  • seeing two of them.

  • How would you know if you're seeing one or two?

  • Well, there's only one way I know.

  • You grab one of them and change it and see if the other

  • one changed.

  • And it didn't, so there's two of them.

  • And, on the other hand, there is some other screwy

  • properties of things like that.

  • Like, how do we know if something changed?

  • We have to look at it before and after the change.

  • The change is an assignment, it's a moment in time.

  • But that means we have to know it was the same one that we're

  • looking at.

  • So some very strange, and unusual, and obscure, and--

  • I don't understand the problems associated with

  • assignment, and change, and objects.

  • These could get very, very bad.

  • For example, here I am, I am a particular person, a

  • particular object.

  • Now, I can take out my knife, and cut my fingernail.

  • A piece of my fingernail has fallen off onto the table.

  • I believe I am the same person I was a second ago, but I'm

  • not physically the same in the slightest.

  • I have changed.

  • Why am I the same?

  • What is the identity of me?

  • I don't know.

  • Except for the fact that I have some sort of identity.

  • And so, I think by introducing assignment and objects, we

  • have opened ourselves up to all the horrible questions of

  • philosophy that have been plaguing philosophers for some

  • thousands of years about this sort of thing.

  • It's why mathematics is a lot cleaner.

  • Let's look at the best things I know to say about actions

  • and identity.

  • We say that an action, a, had an effect on an object, x, or

  • equivalently, that x was changed by a, if some

  • property, p, which was true of x before a, became

  • false of x after a.

  • Let's test. It still means I have to have the

  • x before and after.

  • Or, the other way of saying this is, we say that two

  • objects x and y are the same for any action which has an

  • effect on x has the same effect on y.

  • However, objects are very useful, as I said, for

  • intellectual economy.

  • One of the things that's incredibly useful about them,

  • is that the world is, we like to think about, made out of

  • independent objects with independent local state.

  • We like to think that way, although it

  • isn't completely true.

  • When we want to make very complicated programs that deal

  • with such a world, if we want those programs to be

  • understandable by us and also to be changeable, so that if

  • we change the world we change the program only a little bit,

  • then we want there to be connections, isomorphism,

  • between the objects in the world and the objects in our

  • mental model.

  • The modularity of the world can give us the modularity in

  • our programming.

  • So we invent things called object-oriented programming

  • and things like that to provide us with that power.

  • But it's even easier.

  • Let's play a little game.

  • I want to play a little game, show you an even easier

  • example of where modularity can be enhanced by using an

  • assignment statement, judiciously.

  • One thing I want to enforce and impress on you, is don't

  • use assignment statements the way you use it in FORTRAN or

  • Basic or something or Pascal, to do the things you don't

  • have to do with it.

  • It's not the right way to think for most things.

  • Sometimes it's essential, or maybe it's essential.

  • We'll see more about that too.

  • OK, let me show you a fun game here.

  • There was mathematician by the name of Cesaro--

  • or Cesaro, Cesaro I suppose it is--

  • who figured out a clever way of computing pi.

  • It turns out that if I take to random numbers, two integers

  • at random, and compute the greatest common divisor, their

  • greatest common divisor is either one or it's not one.

  • If it's one, then they have no common divisors.

  • If their greatest common divisor is one--

  • the probability that two random numbers, two numbers

  • chosen at random, has as greatest common divisor one is

  • related to pi.

  • In fact--

  • yes, it's very strange--

  • of course there are other ways of computing pi, like dropping

  • pins on flags, and things like that, and sort of the same

  • kind of thing.

  • So the probability of that the GCD of number one and number

  • two, two random numbers chosen, is 6 over pi squared.

  • I'm not going to try to prove that.

  • It's actually not too hard and sort of fun.

  • How would we estimate such probability?

  • Well, the way we do that, the way we estimate probabilities,

  • is by doing lots of experiments, and then

  • computing the ratios of the ones that come out one way to

  • the total number of experiments we do.

  • It's called Monte Carlo, and it's useful in other contexts

  • for doing things like integrals where you have lots

  • and lots of variables--

  • the space which is limiting the dimensions you are doing

  • you integral in.

  • But going back to here, Let's look at this slide, We can use

  • Cesaro's method for estimating pi with n trials by taking the

  • square root of six over a Monte Carlo, a Monte Carlo

  • experiment with n trials, using Cesaro's experiment,

  • where Cesaro's experiment is the test of whether the GCD of

  • two random numbers--

  • And you can see that I've already got some assignments

  • in here, just by what I wrote.

  • The fact that this word rand, in parentheses, therefore,

  • that procedure call, yields a different value than this one,

  • at least that's what I'm assuming by writing this this

  • way, indicates that this is not a function, that there's

  • internal state in it which is changing.

  • If the GCD of those two random numbers is equal to one,

  • that's the experiment.

  • So here I have an experimental method for estimating the

  • value of pi.

  • Where, I can easily divide this problem into two parts.

  • One is the specific Monte Carlo experiment of Cesaro,

  • which you just saw, and the other is the general technique

  • of doing Monte Carlo experiments.

  • And that's what this is.

  • If I want to do Monte Carlo experiments with n trials, a

  • certain number of trials, and a particular experiment, the

  • way I do that is I make a little iterative procedure

  • which has variable the number of trials remaining and the

  • number trials that have been passed, that I've gotten true.

  • And if the number remaining is 0, then the answer is the

  • number past divided by this whole number of trials, was

  • the estimate of the probability.

  • And if it's not, if I have more trials to do,

  • then let's do one.

  • We do an experiment.

  • We call the procedure which is experiment on no arguments.

  • We do the experiment and then, if that turned out to be true,

  • we go around the loop decrementing the number of

  • experiments we have to do by one and incrementing the

  • number that were passed.

  • And if the experiment was false, we just go around the

  • loop decrementing the number of experiments remaining and

  • keeping the number passed the same.

  • We start this up iterating over the total number of

  • trials with 0 experiments past. A very

  • elegant little program.

  • And I don't have to just do this with Cesaro's experiment,

  • it could be lots of Monte Carlo experiments I might do.

  • Of course, this depends upon the existence of some sort of

  • random number generator.

  • And random number generators generally look

  • something like this.

  • There is a random number generator--

  • is in fact a procedure which is going to do something just

  • like the counter.

  • It's going to update an x to the result of applying some

  • function to x, where this function is some screwy kind

  • of function that you might find out in Knuth's books on

  • the details of programming.

  • He does these wonderful books that are full of the details

  • of programming, because I can't remember how to make a

  • random number generator, but I can look it up there, and I

  • can find out.

  • And then, eventually, I return the value of x which is the

  • state variable internal to the random number generator.

  • That state variable is initialized

  • somehow, and has a value.

  • And this procedure is defined in the context where that

  • variable is bound.

  • So this is a hidden piece of local state that you see here.

  • And this procedure is defined in that context.

  • Now, that's a very simple thing to do.

  • And it's very nice.

  • Supposing, I didn't want to use assignments.

  • Supposing, I wanted to write this program without

  • assignments.

  • What problems would I have?

  • Well, let's see.

  • I'd like to use the overhead machine here, thank you.

  • First of all, let's look at the whole thing.

  • It's a big story.

  • Unfortunately, which tells you there is something wrong.

  • It's at least that big, and it's monolithic.

  • You don't have to understand or look at the text there

  • right now to see that it's monolithic.

  • It isn't a thing which is Cesaro's experiment.

  • It's not pulled out from the Monte Carlo process.

  • It's not separated.

  • Let's look why.

  • Remember, the constraint here is that every procedure return

  • the same value for the same arguments.

  • Every procedure represents a function.

  • That's a different kind of constraint.

  • Because when I have assignments, I can change some

  • internal state variable.

  • So let's see how that causes things to go wrong.

  • Well, start at the beginning.

  • The estimate of pi looks sort of the same.

  • What I'm doing is I take the square root of six over the

  • random GCD test applied to n, whereas that's what this is.

  • But here, we are beginning to see something funny.

  • The random GCD test of a certain number of trials is

  • just like we had before, an iteration on the number of

  • trials remaining, the number of trials that have been

  • passed, and another variable x.

  • What's that x?

  • That x is the state of the random number generator.

  • And it is now going to be used here.

  • The same random update function that I have over here

  • is the one I would have used in a random number generator

  • if I were building it the other way, the one I get out

  • of Knuth's books.

  • x is going to get transformed into x1, I

  • need two random numbers.

  • And x1 is going to get transformed into x2, I have

  • two random numbers.

  • I then have to do exactly what I did before.

  • I take the GCD of x1 x2.

  • If that's one, then I go around the loop with x2 being

  • the next value of x.

  • You see what's happened here is that the state of the

  • random number generator is no longer confined to the insides

  • of the random number generator.

  • It has leaked out.

  • It has leaked out into my procedure that does the Monte

  • Carlo experiment.

  • But what's worse than that, is it's also, because it was

  • contained inside my experiment itself, Cesaro, it leaked out

  • of that too.

  • Because Cesaro called twice, has to have a different value

  • each time, if I going to have a legitimate experimental

  • test. So Cesaro can't be a function either, unless I pass

  • it the seed of the random number generator that is going

  • to go wandering around.

  • So unfortunately, the seed of random number generator has

  • leaked out into Cesaro, from the random number generator,

  • that's leaked into the Monte Carlo experiment.

  • And, unfortunately, my Monte Carlo experiment here is no

  • longer general.

  • The Monte Carlo experiment here knows how many random

  • numbers I need to do the experiment.

  • That's sort of horrible.

  • I lost an ability to decompose a problem into pieces, because

  • I wasn't willing to accept the little loop of information,

  • the feedback process, that happens inside the random

  • number generator before that was made by having an

  • assignment to a state variable that was confined to the

  • random number generator.

  • So the fact that the random number generator is an object,

  • with an internal state variable, it's affected by

  • nothing, but it'll give you something, and it will apply

  • it's force to you, that was what we're missing now.

  • OK, well I think we've seen enough reason for doing this,

  • and it all sort of looks very wonderful.

  • Wouldn't it be nice if assignment was a good thing

  • and maybe it's worth it, but I'm not sure.

  • As Mr. Gilbert and Sullivan said, things are seldom what

  • they seem, skim milk masquerades as cream.

  • Are there any questions?

  • Are there any philosophers here?

  • Anybody want to argue about objects?

  • You're just floored, right?

  • And you haven't done your homework yet.

  • You haven't come up with a good question.

  • Oh, well.

  • Sure, thank you.

  • Let's take the long break now.

[MUSIC PLAYING]

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

B1 中級

第5A講:任務、狀態和副作用。 (Lecture 5A: Assignment, State, and Side-effects)

  • 2 0
    林宜悉 發佈於 2021 年 01 月 14 日
影片單字