diff --git a/SrtEN/lec9b_512kb.mp4.srt b/SrtEN/lec9b_512kb.mp4.srt index 442fa50..f5e4a60 100644 --- a/SrtEN/lec9b_512kb.mp4.srt +++ b/SrtEN/lec9b_512kb.mp4.srt @@ -1,6124 +1,4500 @@ -0 -00:00:00,000 --> 00:00:15,840 - - -1 -00:00:15,840 --> 00:00:20,260 -PROFESSOR: Well, I hope you -appreciate that we have - -2 -00:00:20,260 --> 00:00:26,690 -inducted you into some real -magic, the magic of building - -3 -00:00:26,690 --> 00:00:29,730 -languages, really building -new languages. - -4 -00:00:29,730 --> 00:00:30,430 -What have we looked at? - -5 -00:00:30,430 --> 00:00:39,390 -We've looked at an Escher -picture language: this - -6 -00:00:39,390 --> 00:00:42,360 -language invented by -Peter Henderson. - -7 -00:00:42,360 --> 00:00:46,260 -We looked at digital -logic language. - -8 -00:00:46,260 --> 00:00:53,260 - - -9 -00:00:53,260 --> 00:00:53,570 -Let's see. - -10 -00:00:53,570 --> 00:00:55,360 -We've looked at the -query language. - -11 -00:00:55,360 --> 00:00:59,700 - - -12 -00:00:59,700 --> 00:01:01,570 -And the thing you should realize -is, even though these - -13 -00:01:01,570 --> 00:01:06,760 -were toy examples, they really -are the kernels of really - -14 -00:01:06,760 --> 00:01:08,250 -useful things. - -15 -00:01:08,250 --> 00:01:12,520 -So, for instance, the Escher -picture language was taken by - -16 -00:01:12,520 --> 00:01:17,320 -Henry Wu, who's a student at -MIT, and developed into a real - -17 -00:01:17,320 --> 00:01:21,840 -language for laying out PC -boards based just on extending - -18 -00:01:21,840 --> 00:01:23,300 -those structures. - -19 -00:01:23,300 --> 00:01:25,320 -And the digital logic language, -Jerry mentioned when - -20 -00:01:25,320 --> 00:01:28,550 -he showed it to you, was really -extended to be used as - -21 -00:01:28,550 --> 00:01:32,050 -the basis for a simulator -that was used to - -22 -00:01:32,050 --> 00:01:33,460 -design a real computer. - -23 -00:01:33,460 --> 00:01:34,900 -And the query language, -of course, is kind - -24 -00:01:34,900 --> 00:01:37,510 -of the germ of prologue. - -25 -00:01:37,510 --> 00:01:39,830 -So we built all of these -languages, they're - -26 -00:01:39,830 --> 00:01:41,080 -all based on LISP. - -27 -00:01:41,080 --> 00:01:43,630 - - -28 -00:01:43,630 --> 00:01:48,010 -A lot of people ask what -particular problems is LISP - -29 -00:01:48,010 --> 00:01:48,820 -good for solving for? - -30 -00:01:48,820 --> 00:01:52,150 -The answer is LISP is not good -for solving any particular - -31 -00:01:52,150 --> 00:01:56,340 -problems. What LISP is good for -is constructing within it - -32 -00:01:56,340 --> 00:01:58,140 -the right language to solve -the problems you want to - -33 -00:01:58,140 --> 00:02:01,470 -solve, and that's how you -should think about it. - -34 -00:02:01,470 --> 00:02:04,326 -So all of these languages -were based on LISP. - -35 -00:02:04,326 --> 00:02:07,270 -Now, what's LISP based on? - -36 -00:02:07,270 --> 00:02:07,920 -Where's that come from? - -37 -00:02:07,920 --> 00:02:09,400 -Well, we looked at that too. - -38 -00:02:09,400 --> 00:02:12,740 - - -39 -00:02:12,740 --> 00:02:23,760 -We looked at the meta-circular -evaluator and said well, LISP - -40 -00:02:23,760 --> 00:02:25,810 -is based on LISP. - -41 -00:02:25,810 --> 00:02:28,910 -And when we start looking at -that, we've got to do some - -42 -00:02:28,910 --> 00:02:29,950 -real magic, right? - -43 -00:02:29,950 --> 00:02:31,660 -So what does that mean, right? - -44 -00:02:31,660 --> 00:02:37,730 -Why operators, and fixed points, -and the idea that what - -45 -00:02:37,730 --> 00:02:40,460 -this means is that LISP is -somehow the fixed-point - -46 -00:02:40,460 --> 00:02:44,600 -equation for this funny set of -things which are defined in - -47 -00:02:44,600 --> 00:02:47,470 -terms of themselves. - -48 -00:02:47,470 --> 00:02:49,070 -Now, it's real magic. - -49 -00:02:49,070 --> 00:02:53,000 -Well, today, for a final piece -of magic, we're going to make - -50 -00:02:53,000 --> 00:02:54,250 -all the magic go away. - -51 -00:02:54,250 --> 00:03:06,430 - - -52 -00:03:06,430 --> 00:03:09,770 -We already know how -to do that. - -53 -00:03:09,770 --> 00:03:11,970 -The idea is, we're going to -take the register machine - -54 -00:03:11,970 --> 00:03:14,380 -architecture and show -how to implement - -55 -00:03:14,380 --> 00:03:15,500 -LISP on terms of that. - -56 -00:03:15,500 --> 00:03:22,640 -And, remember, the idea of the -register machine is that - -57 -00:03:22,640 --> 00:03:24,800 -there's a fixed and finite -part of the machine. - -58 -00:03:24,800 --> 00:03:27,050 -There's a finite-state -controller, which does some - -59 -00:03:27,050 --> 00:03:30,510 -particular thing with a -particular amount of hardware. - -60 -00:03:30,510 --> 00:03:32,470 -There are particular data -paths: the operation the - -61 -00:03:32,470 --> 00:03:33,550 -machine does. - -62 -00:03:33,550 --> 00:03:35,780 -And then, in order to implement -recursion and - -63 -00:03:35,780 --> 00:03:38,460 -sustain the illusion of -infinity, there's some large - -64 -00:03:38,460 --> 00:03:42,060 -amount of memory, which -is the stack. - -65 -00:03:42,060 --> 00:03:47,280 -So, if we implement LISP in -terms of a register machine, - -66 -00:03:47,280 --> 00:03:48,900 -then everything ought to -become, at this point, - -67 -00:03:48,900 --> 00:03:49,850 -completely concrete. - -68 -00:03:49,850 --> 00:03:51,650 -All the magic should go away. - -69 -00:03:51,650 --> 00:03:55,140 -And, by the end of this talk, -I want you get the feeling - -70 -00:03:55,140 --> 00:03:58,400 -that, as opposed to this very -mysterious meta-circular - -71 -00:03:58,400 --> 00:04:01,630 -evaluator, that a LISP evaluator -really is something - -72 -00:04:01,630 --> 00:04:03,740 -that's concrete enough that -you can hold in the - -73 -00:04:03,740 --> 00:04:04,720 -palm of your hand. - -74 -00:04:04,720 --> 00:04:06,950 -You should be able to -imagine holding a - -75 -00:04:06,950 --> 00:04:09,546 -LISP interpreter there. - -76 -00:04:09,546 --> 00:04:10,950 -All right, how are we -going to do this? - -77 -00:04:10,950 --> 00:04:13,960 -We already have all -the ingredients. - -78 -00:04:13,960 --> 00:04:18,300 -See, what you learned last time -from Jerry is how to take - -79 -00:04:18,300 --> 00:04:23,980 -any particular couple of LISP -procedures and hand-translate - -80 -00:04:23,980 --> 00:04:28,210 -them into something that runs -on a register machine. - -81 -00:04:28,210 --> 00:04:30,900 -So, to implement all of LISP on -a register machine, all we - -82 -00:04:30,900 --> 00:04:34,010 -have to do is take the -particular procedures that are - -83 -00:04:34,010 --> 00:04:37,450 -the meta-circular evaluator and -hand-translate them for a - -84 -00:04:37,450 --> 00:04:39,120 -register machine. - -85 -00:04:39,120 --> 00:04:42,320 -And that does all -of LISP, right? - -86 -00:04:42,320 --> 00:04:45,380 -So, in principle, we already -know how to do this. - -87 -00:04:45,380 --> 00:04:51,640 -And, indeed, it's going to be -no different, in kind, from - -88 -00:04:51,640 --> 00:04:53,430 -translating, say, recursive -factorial - -89 -00:04:53,430 --> 00:04:54,670 -or recursive Fibonacci. - -90 -00:04:54,670 --> 00:04:56,840 -It's just bigger and -there's more of it. - -91 -00:04:56,840 --> 00:04:58,760 -So it'd just be more details, -but nothing really - -92 -00:04:58,760 --> 00:05:01,730 -conceptually new. - -93 -00:05:01,730 --> 00:05:03,600 -All right, also, when we've done -that, and the thing is - -94 -00:05:03,600 --> 00:05:06,990 -completely explicit, and we see -how to implement LISP in - -95 -00:05:06,990 --> 00:05:10,510 -terms of the actual sequential -register operations, that's - -96 -00:05:10,510 --> 00:05:13,230 -going to be our final most -explicit model of - -97 -00:05:13,230 --> 00:05:14,810 -LISP in this course. - -98 -00:05:14,810 --> 00:05:16,410 -And, remember, that's -a progression - -99 -00:05:16,410 --> 00:05:16,950 -through this course. - -100 -00:05:16,950 --> 00:05:18,790 -We started out with -substitution, which is sort of - -101 -00:05:18,790 --> 00:05:20,370 -like algebra. - -102 -00:05:20,370 --> 00:05:22,070 -And then we went to the -environment model, which - -103 -00:05:22,070 --> 00:05:24,230 -talked about the actual -frames and how - -104 -00:05:24,230 --> 00:05:26,390 -they got linked together. - -105 -00:05:26,390 --> 00:05:28,100 -And then we made that -more concrete in the - -106 -00:05:28,100 --> 00:05:31,080 -meta-circular evaluator. - -107 -00:05:31,080 --> 00:05:33,120 -There are things the -meta-circular evaluator - -108 -00:05:33,120 --> 00:05:34,360 -doesn't tell us. - -109 -00:05:34,360 --> 00:05:36,090 -You should realize that. - -110 -00:05:36,090 --> 00:05:40,420 -For instance, it left unanswered -the question of how - -111 -00:05:40,420 --> 00:05:46,100 -a procedure, like recursive -factorial here , somehow takes - -112 -00:05:46,100 --> 00:05:47,210 -space that grows. - -113 -00:05:47,210 --> 00:05:51,160 -On the other hand, a procedure -which also looks syntactically - -114 -00:05:51,160 --> 00:05:56,760 -recursive, called fact-iter, -somehow doesn't take space. - -115 -00:05:56,760 --> 00:06:01,040 -We justify that it doesn't need -to take space by showing - -116 -00:06:01,040 --> 00:06:01,960 -the substitution model. - -117 -00:06:01,960 --> 00:06:05,550 -But we didn't really say how -it happens that the machine - -118 -00:06:05,550 --> 00:06:09,210 -manages to do that, that that -has to do with the details of - -119 -00:06:09,210 --> 00:06:12,520 -how arguments are passed -to procedures. - -120 -00:06:12,520 --> 00:06:14,710 -And that's the thing we didn't -see in the meta-circular - -121 -00:06:14,710 --> 00:06:17,930 -evaluator precisely because the -way arguments got passed - -122 -00:06:17,930 --> 00:06:21,840 -to procedures in this LISP -depended on the way arguments - -123 -00:06:21,840 --> 00:06:23,510 -got passed to procedures -in this LISP. - -124 -00:06:23,510 --> 00:06:26,070 - - -125 -00:06:26,070 --> 00:06:30,740 -But, now, that's going to become -extremely explicit. - -126 -00:06:30,740 --> 00:06:31,230 -OK. - -127 -00:06:31,230 --> 00:06:35,000 -Well, before going on to the -evaluator, let me just give - -128 -00:06:35,000 --> 00:06:37,940 -you a sense of what a whole LISP -system looks like so you - -129 -00:06:37,940 --> 00:06:39,730 -can see the parts we're going -to talk about and the parts - -130 -00:06:39,730 --> 00:06:43,250 -we're not going to talk about. - -131 -00:06:43,250 --> 00:06:49,240 -Let's see, over here is a happy -LISP user, and the LISP - -132 -00:06:49,240 --> 00:06:52,525 -user is talking to something -called the reader. - -133 -00:06:52,525 --> 00:07:00,360 - - -134 -00:07:00,360 --> 00:07:14,170 -The reader's job in life is to -take characters from the user - -135 -00:07:14,170 --> 00:07:17,960 -and turn them into data -structures in something called - -136 -00:07:17,960 --> 00:07:19,210 -a list structure memory. - -137 -00:07:19,210 --> 00:07:29,783 - - -138 -00:07:29,783 --> 00:07:33,110 -All right, so the reader is -going to take symbols, - -139 -00:07:33,110 --> 00:07:36,600 -parentheses, and A's and B's, -and ones and threes that you - -140 -00:07:36,600 --> 00:07:39,460 -type in, and turn these into -actual list structure: pairs, - -141 -00:07:39,460 --> 00:07:42,340 -and pointers, and things. - -142 -00:07:42,340 --> 00:07:44,180 -And so, by the time evaluator -is going, there are no - -143 -00:07:44,180 --> 00:07:45,850 -characters in the world. - -144 -00:07:45,850 --> 00:07:49,480 -And, of course, in more modern -list systems, there's sort of - -145 -00:07:49,480 --> 00:07:51,770 -a big morass here that might sit -between the user and the - -146 -00:07:51,770 --> 00:07:55,390 -reader: Windows systems, and top -levels, and mice, and all - -147 -00:07:55,390 --> 00:07:56,280 -kinds of things. - -148 -00:07:56,280 --> 00:07:59,590 -But conceptually, characters -are coming in. - -149 -00:07:59,590 --> 00:08:06,240 -All right, the reader transforms -these into pointers - -150 -00:08:06,240 --> 00:08:09,940 -to stuff in this memory, -and that's what the - -151 -00:08:09,940 --> 00:08:17,090 -evaluator sees, OK? - -152 -00:08:17,090 --> 00:08:19,780 -The evaluator has a -bunch of helpers. - -153 -00:08:19,780 --> 00:08:23,080 -It has all possible primitive -operators you might want. - -154 -00:08:23,080 --> 00:08:29,610 -So there's a completely separate -box, a floating point - -155 -00:08:29,610 --> 00:08:33,340 -unit, or all sorts of -things, which do - -156 -00:08:33,340 --> 00:08:35,960 -the primitive operators. - -157 -00:08:35,960 --> 00:08:38,240 -And, if you want more special -primitives, you build more - -158 -00:08:38,240 --> 00:08:39,309 -primitive operators, -but they're - -159 -00:08:39,309 --> 00:08:42,080 -separate from the evaluator. - -160 -00:08:42,080 --> 00:08:46,150 -The evaluator finally gets an -answer and communicates that - -161 -00:08:46,150 --> 00:08:47,400 -to the printer. - -162 -00:08:47,400 --> 00:08:50,780 - - -163 -00:08:50,780 --> 00:08:52,980 -And now, the printer's job in -life is to take this list - -164 -00:08:52,980 --> 00:08:56,150 -structure coming from the -evaluator, and turn it back - -165 -00:08:56,150 --> 00:09:03,630 -into characters, and communicate -them to the user - -166 -00:09:03,630 --> 00:09:05,540 -through whatever interface -there is. - -167 -00:09:05,540 --> 00:09:08,050 - - -168 -00:09:08,050 --> 00:09:08,810 -OK. - -169 -00:09:08,810 --> 00:09:10,100 -Well, today, what we're -going to talk - -170 -00:09:10,100 --> 00:09:12,670 -about is this evaluator. - -171 -00:09:12,670 --> 00:09:14,900 -The primitive operators have -nothing particular to do with - -172 -00:09:14,900 --> 00:09:17,430 -LISP, they're however you like -to implement primitive - -173 -00:09:17,430 --> 00:09:19,440 -operations. - -174 -00:09:19,440 --> 00:09:22,370 -The reader and printer are -actually complicated, but - -175 -00:09:22,370 --> 00:09:24,420 -we're not going to -talk about them. - -176 -00:09:24,420 --> 00:09:27,410 -They sort of have to do with -details of how you might build - -177 -00:09:27,410 --> 00:09:29,900 -up list structure -from characters. - -178 -00:09:29,900 --> 00:09:31,650 -So that is a long story, -but we're not going - -179 -00:09:31,650 --> 00:09:32,490 -to talk about it. - -180 -00:09:32,490 --> 00:09:36,930 -The list structure memory, we'll -talk about next time. - -181 -00:09:36,930 --> 00:09:39,170 -So, pretty much, except for -the details of reading and - -182 -00:09:39,170 --> 00:09:41,860 -printing, the only mystery -that's going to be left after - -183 -00:09:41,860 --> 00:09:44,950 -you see the evaluator is how -you build list structure on - -184 -00:09:44,950 --> 00:09:46,295 -conventional memories. - -185 -00:09:46,295 --> 00:09:50,580 -But we'll worry about -that next time too. - -186 -00:09:50,580 --> 00:09:51,830 -OK. - -187 -00:09:51,830 --> 00:09:53,350 - - -188 -00:09:53,350 --> 00:09:56,110 -Well, let's start talking -about the evaluator. - -189 -00:09:56,110 --> 00:09:59,970 -The one that we're going to show -you, of course, is not, I - -190 -00:09:59,970 --> 00:10:01,120 -think, nothing special -about it. - -191 -00:10:01,120 --> 00:10:03,040 -It's just a particular register - -192 -00:10:03,040 --> 00:10:04,810 -machine that runs LISP. - -193 -00:10:04,810 --> 00:10:08,280 -And it has seven registers, -and here - -194 -00:10:08,280 --> 00:10:09,890 -are the seven registers. - -195 -00:10:09,890 --> 00:10:16,430 -There's a register, called EXP, -and its job is to hold - -196 -00:10:16,430 --> 00:10:18,370 -the expression to -be evaluated. - -197 -00:10:18,370 --> 00:10:22,660 -And by that, I mean it's going -to hold a pointer to someplace - -198 -00:10:22,660 --> 00:10:24,040 -in list structure memory -that holds the - -199 -00:10:24,040 --> 00:10:26,550 -expression to be evaluated. - -200 -00:10:26,550 --> 00:10:29,490 -There's a register, called -ENV, which holds the - -201 -00:10:29,490 --> 00:10:34,070 -environment in which this -expression is to be evaluated. - -202 -00:10:34,070 --> 00:10:34,940 -And, again, I made a pointer. - -203 -00:10:34,940 --> 00:10:38,240 -The environment is some -data structure. - -204 -00:10:38,240 --> 00:10:41,390 -There's a register, called -FUN, which will hold the - -205 -00:10:41,390 --> 00:10:44,630 -procedure to be applied when you -go to apply a procedure. - -206 -00:10:44,630 --> 00:10:48,210 -A register, called ARGL, -which wants the list - -207 -00:10:48,210 --> 00:10:50,630 -of evaluated arguments. - -208 -00:10:50,630 --> 00:10:52,060 -What you can start seeing -here is the basic - -209 -00:10:52,060 --> 00:10:53,140 -structure of the evaluator. - -210 -00:10:53,140 --> 00:10:54,490 -Remember how evaluators work. - -211 -00:10:54,490 --> 00:10:57,670 -There's a piece that takes -expressions and environments, - -212 -00:10:57,670 --> 00:10:59,880 -and there's a piece that -takes functions, or - -213 -00:10:59,880 --> 00:11:03,480 -procedures and arguments. - -214 -00:11:03,480 --> 00:11:05,360 -And going back and forth -around here is - -215 -00:11:05,360 --> 00:11:07,740 -the eval/apply loop. - -216 -00:11:07,740 --> 00:11:10,270 -So those are the basic pieces -of the eval and apply. - -217 -00:11:10,270 --> 00:11:11,610 -Then there's some other things, -there's continue. - -218 -00:11:11,610 --> 00:11:15,340 -You just saw before how the -continue register is used to - -219 -00:11:15,340 --> 00:11:19,000 -implement recursion and -stack discipline. - -220 -00:11:19,000 --> 00:11:21,510 -There's a register that's going -to hold the result of - -221 -00:11:21,510 --> 00:11:24,190 -some evaluation. - -222 -00:11:24,190 --> 00:11:25,890 -And then, besides that, -there's one temporary - -223 -00:11:25,890 --> 00:11:29,280 -register, called UNEV, which -typically, in the evaluator, - -224 -00:11:29,280 --> 00:11:32,980 -is going to be used to hold -temporary pieces of the - -225 -00:11:32,980 --> 00:11:34,690 -expression you're working on, -which you haven't gotten - -226 -00:11:34,690 --> 00:11:37,150 -around to evaluate yet, right? - -227 -00:11:37,150 --> 00:11:40,646 -So there's my machine: a -seven-register machine. - -228 -00:11:40,646 --> 00:11:43,300 -And, of course, you might want -to make a machine with a lot - -229 -00:11:43,300 --> 00:11:46,040 -more registers to get better -performance, but this is just - -230 -00:11:46,040 --> 00:11:48,480 -a tiny, minimal one. - -231 -00:11:48,480 --> 00:11:49,780 -Well, how about the -data paths? - -232 -00:11:49,780 --> 00:11:55,100 -This machine has a lot of -special operations for LISP. - -233 -00:11:55,100 --> 00:12:00,120 -So, here are some typical -data paths. - -234 -00:12:00,120 --> 00:12:03,410 -A typical one might be, oh, -assign to the VAL register the - -235 -00:12:03,410 --> 00:12:06,710 -contents of the EXP register. - -236 -00:12:06,710 --> 00:12:10,190 -In terms of those diagrams you -saw, that's a little button on - -237 -00:12:10,190 --> 00:12:11,900 -some arrow. - -238 -00:12:11,900 --> 00:12:14,040 -Here's a more complicated one. - -239 -00:12:14,040 --> 00:12:18,810 -It says branch, if the thing in -the expression register is - -240 -00:12:18,810 --> 00:12:21,820 -a conditional to some label -here, called the - -241 -00:12:21,820 --> 00:12:23,850 -ev-conditional. - -242 -00:12:23,850 --> 00:12:25,680 -And you can imagine this -implemented in a lot of - -243 -00:12:25,680 --> 00:12:26,230 -different ways. - -244 -00:12:26,230 --> 00:12:28,950 -You might imagine this -conditional test as a special - -245 -00:12:28,950 --> 00:12:32,180 -purpose sub-routine, and -conditional might be - -246 -00:12:32,180 --> 00:12:34,400 -represented as some data -abstraction that you don't - -247 -00:12:34,400 --> 00:12:36,610 -care about at this -level of detail. - -248 -00:12:36,610 --> 00:12:37,980 -So that might be done -as a sub-routine. - -249 -00:12:37,980 --> 00:12:41,200 -This might be a machine with -hardware-types, and - -250 -00:12:41,200 --> 00:12:42,910 -conditional might be testing -some bits for - -251 -00:12:42,910 --> 00:12:45,350 -a particular code. - -252 -00:12:45,350 --> 00:12:47,280 -There are all sorts of ways -that's beneath the level of - -253 -00:12:47,280 --> 00:12:50,190 -abstraction we're looking at. - -254 -00:12:50,190 --> 00:12:52,610 -Another kind of operation, and -there are a lot of different - -255 -00:12:52,610 --> 00:12:55,880 -operations assigned to -EXP, the first clause - -256 -00:12:55,880 --> 00:12:56,840 -of what's in EXP. - -257 -00:12:56,840 --> 00:12:59,260 -This might be part of processing -a conditional. - -258 -00:12:59,260 --> 00:13:03,810 -And, again, first clause is some -selector whose details we - -259 -00:13:03,810 --> 00:13:04,470 -don't care about. - -260 -00:13:04,470 --> 00:13:06,670 -And you can, again, imagine that -as a sub-routine which'll - -261 -00:13:06,670 --> 00:13:09,180 -do some list operations, or -you can imagine that as - -262 -00:13:09,180 --> 00:13:12,170 -something that's built directly -into hardware. - -263 -00:13:12,170 --> 00:13:14,580 -The reason I keep saying you can -imagine it built directly - -264 -00:13:14,580 --> 00:13:18,360 -into hardware is even though -there are a lot of operations, - -265 -00:13:18,360 --> 00:13:19,740 -there are still a fixed -number of them. - -266 -00:13:19,740 --> 00:13:22,370 -I forget how many, maybe 150. - -267 -00:13:22,370 --> 00:13:24,360 -So, it's plausible to think -of building these - -268 -00:13:24,360 --> 00:13:26,400 -directly into hardware. - -269 -00:13:26,400 --> 00:13:28,500 -Here's a more complicated one. - -270 -00:13:28,500 --> 00:13:29,940 -You can see this has to -do with looking up - -271 -00:13:29,940 --> 00:13:31,710 -the values of variables. - -272 -00:13:31,710 --> 00:13:34,370 -It says assign to the VAL -register the result of looking - -273 -00:13:34,370 --> 00:13:39,310 -up the variable value of some -particular expression, which, - -274 -00:13:39,310 --> 00:13:41,330 -in this case, is supposed -to be a variable in some - -275 -00:13:41,330 --> 00:13:42,850 -environment. - -276 -00:13:42,850 --> 00:13:46,650 -And this'll be some operation -that searches through the - -277 -00:13:46,650 --> 00:13:49,860 -environment structure, however -it is represented, and goes - -278 -00:13:49,860 --> 00:13:52,240 -and looks up that variable. - -279 -00:13:52,240 --> 00:13:54,360 -And, again, that's below the -level of detail that we're - -280 -00:13:54,360 --> 00:13:55,790 -thinking about. - -281 -00:13:55,790 --> 00:13:58,350 -This has to do with the details -of the data structures - -282 -00:13:58,350 --> 00:14:00,380 -for representing environments. - -283 -00:14:00,380 --> 00:14:04,410 -But, anyway, there is this fixed -and finite number of - -284 -00:14:04,410 --> 00:14:05,940 -operations in the register -machine. - -285 -00:14:05,940 --> 00:14:08,500 - - -286 -00:14:08,500 --> 00:14:11,720 -Well, what's its overall -structure? - -287 -00:14:11,720 --> 00:14:14,930 -Those are some typical -operations. - -288 -00:14:14,930 --> 00:14:17,060 -Remember what we have to -do, we have to take the - -289 -00:14:17,060 --> 00:14:20,172 -meta-circular evaluator-- - -290 -00:14:20,172 --> 00:14:22,890 -and here's a piece of the -meta-circular evaluator. - -291 -00:14:22,890 --> 00:14:28,310 -This is the one using abstract -syntax that's in the book. - -292 -00:14:28,310 --> 00:14:30,500 -It's a little bit different -from the one - -293 -00:14:30,500 --> 00:14:33,500 -that Jerry shows you. - -294 -00:14:33,500 --> 00:14:37,950 -And the main thing to remember -about the evaluator is that - -295 -00:14:37,950 --> 00:14:40,310 -it's doing some sort of case -analysis on the kinds of - -296 -00:14:40,310 --> 00:14:46,120 -expressions: so if it's either -self-evaluated, or quoted, or - -297 -00:14:46,120 --> 00:14:48,560 -whatever else. - -298 -00:14:48,560 --> 00:14:51,620 -And then, in the general case -where the expression it's - -299 -00:14:51,620 --> 00:14:54,280 -looking at is an application, -there's some tricky - -300 -00:14:54,280 --> 00:14:55,750 -recursions going on. - -301 -00:14:55,750 --> 00:15:00,730 -First of all, eval has to call -itself both to evaluate the - -302 -00:15:00,730 --> 00:15:05,880 -operator and to evaluate -all the operands. - -303 -00:15:05,880 --> 00:15:08,470 -So there's this sort of red -recursion of values walking - -304 -00:15:08,470 --> 00:15:12,270 -down the tree that's really -the easy recursion. - -305 -00:15:12,270 --> 00:15:14,750 -That's just a val walking down -this tree of expressions. - -306 -00:15:14,750 --> 00:15:16,600 -Then, in the evaluator, there's -a hard recursion. - -307 -00:15:16,600 --> 00:15:18,200 -There's the red to green. - -308 -00:15:18,200 --> 00:15:19,450 -Eval calls apply. - -309 -00:15:19,450 --> 00:15:22,470 - - -310 -00:15:22,470 --> 00:15:26,132 -That's the case where evaluating -a procedure or - -311 -00:15:26,132 --> 00:15:28,920 -argument reduces to applying -the procedure - -312 -00:15:28,920 --> 00:15:30,370 -to the list of arguments. - -313 -00:15:30,370 --> 00:15:31,700 -And then, apply comes -over here. - -314 -00:15:31,700 --> 00:15:34,770 - - -315 -00:15:34,770 --> 00:15:39,270 -Apply takes a procedure and -arguments and, in the general - -316 -00:15:39,270 --> 00:15:41,950 -case where there's a compound -procedure, apply goes around - -317 -00:15:41,950 --> 00:15:44,560 -and green calls red. - -318 -00:15:44,560 --> 00:15:48,170 -Apply comes around and -calls eval again. - -319 -00:15:48,170 --> 00:15:51,330 -Eval's the body of the procedure -in the result of - -320 -00:15:51,330 --> 00:15:54,600 -extending the environment with -the parameters of the - -321 -00:15:54,600 --> 00:15:56,605 -procedure by binding -the arguments. - -322 -00:15:56,605 --> 00:15:59,620 - - -323 -00:15:59,620 --> 00:16:01,560 -Except in the primitive case, -where it just calls something - -324 -00:16:01,560 --> 00:16:03,550 -else primitive-apply, which -is not really the - -325 -00:16:03,550 --> 00:16:05,980 -business of the evaluator. - -326 -00:16:05,980 --> 00:16:11,630 -So this sort of red to green, -to red to green, that's the - -327 -00:16:11,630 --> 00:16:15,130 -eval/apply loop, and that's the -thing that we're going to - -328 -00:16:15,130 --> 00:16:17,186 -want to see in the evaluator. - -329 -00:16:17,186 --> 00:16:19,840 - - -330 -00:16:19,840 --> 00:16:19,970 -All right. - -331 -00:16:19,970 --> 00:16:22,570 -Well, it won't surprise you at -all that the two big pieces of - -332 -00:16:22,570 --> 00:16:27,470 -this evaluator correspond -to eval and apply. - -333 -00:16:27,470 --> 00:16:30,070 -There's a piece called -eval-dispatch, and a piece - -334 -00:16:30,070 --> 00:16:32,110 -called apply-dispatch. - -335 -00:16:32,110 --> 00:16:34,520 -And, before we get into the -details of the code, the way - -336 -00:16:34,520 --> 00:16:37,760 -to understand this is to think, -again, in terms of - -337 -00:16:37,760 --> 00:16:40,430 -these pieces of the evaluator -having contracts with the rest - -338 -00:16:40,430 --> 00:16:41,870 -of the world. - -339 -00:16:41,870 --> 00:16:44,320 -What do they do from the outside -before getting into - -340 -00:16:44,320 --> 00:16:45,780 -the grungy details? - -341 -00:16:45,780 --> 00:16:50,080 -Well, the contract for -eval-dispatch-- - -342 -00:16:50,080 --> 00:16:51,300 -remember, it corresponds -to eval. - -343 -00:16:51,300 --> 00:16:54,100 -It's got to evaluate an -expression in an environment. - -344 -00:16:54,100 --> 00:16:56,840 -So, in particular, what this -one is going to do, - -345 -00:16:56,840 --> 00:16:59,920 -eval-dispatch will assume that, -when you call it, that - -346 -00:16:59,920 --> 00:17:01,460 -the expression you -want to evaluate - -347 -00:17:01,460 --> 00:17:03,640 -is in the EXP register. - -348 -00:17:03,640 --> 00:17:07,680 -The environment in which you -want the evaluation to take - -349 -00:17:07,680 --> 00:17:09,569 -place is in the ENV register. - -350 -00:17:09,569 --> 00:17:12,040 -And continue tells you the place -where the machine should - -351 -00:17:12,040 --> 00:17:13,880 -go next when the evaluation -is done. - -352 -00:17:13,880 --> 00:17:17,440 - - -353 -00:17:17,440 --> 00:17:20,210 -Eval-dispatch's contract is that -it'll actually perform - -354 -00:17:20,210 --> 00:17:23,930 -that evaluation, and, at the end -of which, it'll end up at - -355 -00:17:23,930 --> 00:17:26,619 -the place specified -by continue. - -356 -00:17:26,619 --> 00:17:29,950 -The result of the evaluation -will be in the VAL register. - -357 -00:17:29,950 --> 00:17:33,100 -And it just warns you, it makes -no promises about what - -358 -00:17:33,100 --> 00:17:35,230 -happens to the registers. - -359 -00:17:35,230 --> 00:17:37,490 -All other registers might -be destroyed. - -360 -00:17:37,490 --> 00:17:41,790 -So, there's one piece, OK? - -361 -00:17:41,790 --> 00:17:43,640 -Together, the pieces, -apply-dispatch that - -362 -00:17:43,640 --> 00:17:47,650 -corresponds to apply, it's got -to apply a procedure to some - -363 -00:17:47,650 --> 00:17:52,060 -arguments, so it assumes that -this register, ARGL, contains - -364 -00:17:52,060 --> 00:17:54,540 -a list of the evaluated -arguments. - -365 -00:17:54,540 --> 00:17:57,220 -FUN contains the procedure. - -366 -00:17:57,220 --> 00:17:59,500 -Those correspond to the -arguments to the apply - -367 -00:17:59,500 --> 00:18:01,055 -procedure in the meta-circular -evaluator. - -368 -00:18:01,055 --> 00:18:03,970 - - -369 -00:18:03,970 --> 00:18:06,520 -And apply, in this particular -evaluator, we're going to use - -370 -00:18:06,520 --> 00:18:10,790 -a discipline which says the -place the machine should go to - -371 -00:18:10,790 --> 00:18:14,480 -next when apply is done is, at -the moment apply-dispatch is - -372 -00:18:14,480 --> 00:18:18,850 -called at the top of the stack, -that's just discipline - -373 -00:18:18,850 --> 00:18:21,840 -for the way this particular -machine's organized. - -374 -00:18:21,840 --> 00:18:23,950 -And now apply's contract -is given all that. - -375 -00:18:23,950 --> 00:18:25,540 -It'll perform the application. - -376 -00:18:25,540 --> 00:18:28,890 -The result of that application -will end up in VAL. - -377 -00:18:28,890 --> 00:18:31,120 -The stack will be popped. - -378 -00:18:31,120 --> 00:18:33,460 -And, again, the contents of all -the other registers may be - -379 -00:18:33,460 --> 00:18:35,110 -destroyed, all right? - -380 -00:18:35,110 --> 00:18:39,760 -So that's the basic organization -of this machine. - -381 -00:18:39,760 --> 00:18:41,110 -Let's break for a little bit -and see if there are any - -382 -00:18:41,110 --> 00:18:42,700 -questions, and then we'll -do a real example. - -383 -00:18:42,700 --> 00:19:47,850 - - -384 -00:19:47,850 --> 00:19:51,300 -Well, let's take the register -machine now, and actually step - -385 -00:19:51,300 --> 00:19:57,950 -through, and really, in real -detail, so you see completely - -386 -00:19:57,950 --> 00:20:03,400 -concrete how some expressions -are evaluated, all right? - -387 -00:20:03,400 --> 00:20:06,435 -So, let's start with a very -simple expression. - -388 -00:20:06,435 --> 00:20:09,620 - - -389 -00:20:09,620 --> 00:20:13,320 -Let's evaluate the -expression 1. - -390 -00:20:13,320 --> 00:20:18,880 - - -391 -00:20:18,880 --> 00:20:21,620 -And we need an environment, so -let's imagine that somewhere - -392 -00:20:21,620 --> 00:20:23,085 -there's an environment, -we'll call it E,0. - -393 -00:20:23,085 --> 00:20:30,260 - - -394 -00:20:30,260 --> 00:20:36,230 -And just, since we'll use these -later, we obviously - -395 -00:20:36,230 --> 00:20:38,360 -don't really need anything -to evaluate 1. - -396 -00:20:38,360 --> 00:20:40,810 -But, just for reference later, -let's assume that E,0 has in - -397 -00:20:40,810 --> 00:20:49,140 -it an X that's bound to 3 and -a Y that's bound to 4, OK? - -398 -00:20:49,140 --> 00:20:53,700 -And now what we're going to do -is we're going to evaluate 1 - -399 -00:20:53,700 --> 00:20:59,650 -in this environment, and so the -ENV register has a pointer - -400 -00:20:59,650 --> 00:21:03,560 -to this environment, -E,0, all right? - -401 -00:21:03,560 --> 00:21:05,650 -So let's watch that thing go. - -402 -00:21:05,650 --> 00:21:08,260 -What I'm going to do is -step through the code. - -403 -00:21:08,260 --> 00:21:10,080 -And, let's see, I'll -be the controller. - -404 -00:21:10,080 --> 00:21:12,980 -And now what I need, since this -gets rather complicated, - -405 -00:21:12,980 --> 00:21:16,830 -is a very little -execution unit. - -406 -00:21:16,830 --> 00:21:22,624 -So here's the execution -unit, OK? - -407 -00:21:22,624 --> 00:21:23,874 -OK. - -408 -00:21:23,874 --> 00:21:27,088 - - -409 -00:21:27,088 --> 00:21:28,590 -OK. - -410 -00:21:28,590 --> 00:21:30,690 -All right, now we're -going to start. - -411 -00:21:30,690 --> 00:21:31,710 -We're going to start -the machine at - -412 -00:21:31,710 --> 00:21:33,660 -eval-dispatch, right? - -413 -00:21:33,660 --> 00:21:36,120 -That's the beginning of this. - -414 -00:21:36,120 --> 00:21:39,320 -Eval-dispatch is going to look -at the expression in dispatch, - -415 -00:21:39,320 --> 00:21:42,010 -just like eval where we look -at the very first thing. - -416 -00:21:42,010 --> 00:21:46,990 -We branch on whether or -not this expression is - -417 -00:21:46,990 --> 00:21:47,950 -self-evaluating. - -418 -00:21:47,950 --> 00:21:50,170 -Self-evaluating is some -abstraction we - -419 -00:21:50,170 --> 00:21:52,550 -put into the machine-- - -420 -00:21:52,550 --> 00:21:53,690 -it's going to be true -for numbers-- - -421 -00:21:53,690 --> 00:21:57,040 -to a place called ev-self-eval, -right? - -422 -00:21:57,040 --> 00:22:00,260 -So me, being the controller, -looks at ev-self-eval, so - -423 -00:22:00,260 --> 00:22:02,780 -we'll go over to there. - -424 -00:22:02,780 --> 00:22:09,050 -Ev-self-eval says fine, assign -to val whatever is in the - -425 -00:22:09,050 --> 00:22:15,220 -expression unit, OK? - -426 -00:22:15,220 --> 00:22:19,930 -And I have a bug because what I -didn't do when I initialized - -427 -00:22:19,930 --> 00:22:23,610 -this machine is also say what's -supposed to happen when - -428 -00:22:23,610 --> 00:22:27,640 -it's done, so I should have -started out the machine with - -429 -00:22:27,640 --> 00:22:32,050 -done being in the continue -register, OK? - -430 -00:22:32,050 --> 00:22:33,640 -So we assign to VAL. - -431 -00:22:33,640 --> 00:22:35,790 -And now go to fetch -of continue, and - -432 -00:22:35,790 --> 00:22:38,000 -now change-- - -433 -00:22:38,000 --> 00:22:40,000 -OK. - -434 -00:22:40,000 --> 00:22:42,160 -OK, let's try something -harder. - -435 -00:22:42,160 --> 00:22:47,900 -Let's reset the machine here, -and we'll put in the - -436 -00:22:47,900 --> 00:22:56,710 -expression register, X, OK? - -437 -00:22:56,710 --> 00:22:59,610 -Start again at eval-dispatch. - -438 -00:22:59,610 --> 00:23:01,690 -Check, is it self-evaluating? - -439 -00:23:01,690 --> 00:23:02,650 -No. - -440 -00:23:02,650 --> 00:23:04,630 -Is it a variable? - -441 -00:23:04,630 --> 00:23:05,560 -Yes. - -442 -00:23:05,560 --> 00:23:08,380 -We go off to ev-variable. - -443 -00:23:08,380 --> 00:23:14,700 -It says assign to VAL, look up -the variable value in the - -444 -00:23:14,700 --> 00:23:21,620 -expression register, OK? - -445 -00:23:21,620 --> 00:23:23,625 -Go to fetch of continue. - -446 -00:23:23,625 --> 00:23:24,875 -PROFESSOR: Done. - -447 -00:23:24,875 --> 00:23:27,252 - - -448 -00:23:27,252 --> 00:23:28,950 -PROFESSOR: OK. - -449 -00:23:28,950 --> 00:23:29,430 -All right. - -450 -00:23:29,430 --> 00:23:31,330 -Well, that's the basic idea. - -451 -00:23:31,330 --> 00:23:32,920 -That's a simple operation -of the machine. - -452 -00:23:32,920 --> 00:23:34,600 -Now, let's actually do something -a little bit more - -453 -00:23:34,600 --> 00:23:36,070 -interesting. - -454 -00:23:36,070 --> 00:23:49,678 -Let's look at the expression -the sum of x and y. - -455 -00:23:49,678 --> 00:23:50,130 -OK. - -456 -00:23:50,130 --> 00:23:53,240 -And now we'll see how you -start unrolling these - -457 -00:23:53,240 --> 00:23:57,100 -expression trees, OK? - -458 -00:23:57,100 --> 00:24:00,645 -Well, start again at -eval-dispatch, all right? - -459 -00:24:00,645 --> 00:24:04,610 - - -460 -00:24:04,610 --> 00:24:06,060 -Self-evaluating? - -461 -00:24:06,060 --> 00:24:06,810 -No. - -462 -00:24:06,810 --> 00:24:07,280 -Variable? - -463 -00:24:07,280 --> 00:24:07,850 -No. - -464 -00:24:07,850 --> 00:24:10,270 -All the other special forms -which I didn't write down, - -465 -00:24:10,270 --> 00:24:12,480 -like quote, and lambda, -and set, and whatever, - -466 -00:24:12,480 --> 00:24:13,260 -it's none of those. - -467 -00:24:13,260 --> 00:24:16,520 -It turns out to be an -application, so we go off to - -468 -00:24:16,520 --> 00:24:19,970 -ev-application, OK? - -469 -00:24:19,970 --> 00:24:25,580 -Ev-application, remember what -it's going to do overall. - -470 -00:24:25,580 --> 00:24:28,310 -It is going to evaluate -the operator. - -471 -00:24:28,310 --> 00:24:32,950 -It's going to evaluate the -arguments, and then it's going - -472 -00:24:32,950 --> 00:24:35,060 -to go apply them. - -473 -00:24:35,060 --> 00:24:38,140 -So, before we start, since we're -being very literal, we'd - -474 -00:24:38,140 --> 00:24:40,610 -better remember that, somewhere -in this environment, - -475 -00:24:40,610 --> 00:24:46,010 -it's linked to another -environment in which plus is - -476 -00:24:46,010 --> 00:24:52,380 -bound to the primitive procedure -plus before we get - -477 -00:24:52,380 --> 00:24:55,340 -an unknown variable -in our machine. - -478 -00:24:55,340 --> 00:24:56,590 -OK, so we're at ev-application. - -479 -00:24:56,590 --> 00:24:59,850 - - -480 -00:24:59,850 --> 00:25:05,920 -OK, assign to UNEV the operands -of what's in the - -481 -00:25:05,920 --> 00:25:07,920 -expression register, OK? - -482 -00:25:07,920 --> 00:25:09,230 -Those are the operands. - -483 -00:25:09,230 --> 00:25:11,920 -UNEV's a temporary register -where we're - -484 -00:25:11,920 --> 00:25:12,916 -going to save them. - -485 -00:25:12,916 --> 00:25:13,860 -PROFESSOR: I'm assigning. - -486 -00:25:13,860 --> 00:25:18,070 -PROFESSOR: Assign to -x the operator. - -487 -00:25:18,070 --> 00:25:22,140 -Now, notice we've destroyed that -expression in x, but the - -488 -00:25:22,140 --> 00:25:25,820 -piece that we need is -now in UNEV. OK. - -489 -00:25:25,820 --> 00:25:27,490 -Now, we're going to get -set up to recursively - -490 -00:25:27,490 --> 00:25:28,750 -evaluate the operator. - -491 -00:25:28,750 --> 00:25:31,565 -Save the continue register -on the stack. - -492 -00:25:31,565 --> 00:25:34,870 - - -493 -00:25:34,870 --> 00:25:36,120 -Save the environment. - -494 -00:25:36,120 --> 00:25:40,520 - - -495 -00:25:40,520 --> 00:25:53,210 -Save UNEV. OK, assign -to continue a - -496 -00:25:53,210 --> 00:25:54,460 -label called eval-args. - -497 -00:25:54,460 --> 00:26:01,400 - - -498 -00:26:01,400 --> 00:26:01,980 -Now, what have we done? - -499 -00:26:01,980 --> 00:26:04,380 -We've set up for a -recursive call. - -500 -00:26:04,380 --> 00:26:06,280 -We're about to go to -eval-dispatch. - -501 -00:26:06,280 --> 00:26:10,230 -We've set up for a recursive -call to eval-dispatch. - -502 -00:26:10,230 --> 00:26:11,020 -What did we do? - -503 -00:26:11,020 --> 00:26:15,240 -We took the things we're going -to need later, those operands - -504 -00:26:15,240 --> 00:26:17,860 -that were in UNEV; the -environment in which we're - -505 -00:26:17,860 --> 00:26:20,100 -going to eventually have to, -maybe, evaluate those - -506 -00:26:20,100 --> 00:26:23,910 -operands; the place we -eventually want to go to, - -507 -00:26:23,910 --> 00:26:27,120 -which, in this case, was done; -we've saved them on the stack. - -508 -00:26:27,120 --> 00:26:29,120 -The reason we saved them -on the stack is because - -509 -00:26:29,120 --> 00:26:31,860 -eval-dispatch makes no promises -about what registers - -510 -00:26:31,860 --> 00:26:33,550 -it may destroy. - -511 -00:26:33,550 --> 00:26:35,020 -So all that stuff is -saved on the stack. - -512 -00:26:35,020 --> 00:26:37,380 -Now, we've set up -eval-dispatch's contract. - -513 -00:26:37,380 --> 00:26:41,220 -There's a new expression, which -is the operator plus; a - -514 -00:26:41,220 --> 00:26:44,250 -new environment, although, in -this case, it's the same one; - -515 -00:26:44,250 --> 00:26:45,670 -and a new place to -go to when you're - -516 -00:26:45,670 --> 00:26:47,600 -done, which is eval-args. - -517 -00:26:47,600 --> 00:26:48,130 -So that's set up. - -518 -00:26:48,130 --> 00:26:50,890 -Now, we're going to go -off to eval-dispatch. - -519 -00:26:50,890 --> 00:26:53,090 -Here we are back at -eval-dispatch. - -520 -00:26:53,090 --> 00:26:54,490 -It's not self-evaluating. - -521 -00:26:54,490 --> 00:26:57,270 -Oh, it's a variable, so -we'd better go off to - -522 -00:26:57,270 --> 00:27:00,260 -ev-variable, right? - -523 -00:27:00,260 --> 00:27:02,880 -Ev-variable is assigned -to VAL. - -524 -00:27:02,880 --> 00:27:08,770 -Look up the variable value -of the expression, OK? - -525 -00:27:08,770 --> 00:27:13,000 -So VAL is the primitive -procedure plus, OK? - -526 -00:27:13,000 --> 00:27:15,020 -And go to fetch of continue. - -527 -00:27:15,020 --> 00:27:15,660 -PROFESSOR: Eval-args. - -528 -00:27:15,660 --> 00:27:19,340 -PROFESSOR: Right, which is -now eval-args not done. - -529 -00:27:19,340 --> 00:27:23,210 -So we come back here at -eval-args, and what do we do? - -530 -00:27:23,210 --> 00:27:25,620 -We're going to restore the stuff -that we saved, so we - -531 -00:27:25,620 --> 00:27:31,710 -restore UNEV. And notice, there, -it wasn't necessary, - -532 -00:27:31,710 --> 00:27:32,900 -although, in general, -it would be. - -533 -00:27:32,900 --> 00:27:35,430 -It might be some arbitrary -evaluation that happened. - -534 -00:27:35,430 --> 00:27:51,900 -We restore ENV. OK, we assign -to FUN fetch of VAL. - -535 -00:27:51,900 --> 00:27:58,620 - - -536 -00:27:58,620 --> 00:28:01,650 -OK, now, we're going -to go off and start - -537 -00:28:01,650 --> 00:28:04,340 -evaluating some arguments. - -538 -00:28:04,340 --> 00:28:08,330 -Well, first thing we'd better -do is save FUN because some - -539 -00:28:08,330 --> 00:28:10,165 -arbitrary stuff might happen -in that evaluation. - -540 -00:28:10,165 --> 00:28:15,330 - - -541 -00:28:15,330 --> 00:28:18,590 -We initialize the argument list. -Assign to argl an empty - -542 -00:28:18,590 --> 00:28:25,460 -argument list, and go to -eval-arg-loop, OK? - -543 -00:28:25,460 --> 00:28:29,580 -At eval-arg-loop, the idea -of this is we're going to - -544 -00:28:29,580 --> 00:28:32,620 -evaluate the pieces of the -expressions that are in UNEV, - -545 -00:28:32,620 --> 00:28:36,110 -one by one, and move them from -unevaluated in UNEV to - -546 -00:28:36,110 --> 00:28:38,090 -evaluated in the arg list, OK? - -547 -00:28:38,090 --> 00:28:39,340 -So we save argl. - -548 -00:28:39,340 --> 00:28:43,950 - - -549 -00:28:43,950 --> 00:28:53,960 -We assign to x the first operand -of the stuff in UNEV. - -550 -00:28:53,960 --> 00:28:55,890 -Now, we check and see if that -was the last operand. - -551 -00:28:55,890 --> 00:28:59,190 -In this case, it is -not, all right? - -552 -00:28:59,190 --> 00:29:01,235 -So we save the environment. - -553 -00:29:01,235 --> 00:29:09,170 - - -554 -00:29:09,170 --> 00:29:12,620 -We save UNEV because those -are all things - -555 -00:29:12,620 --> 00:29:13,500 -we might need later. - -556 -00:29:13,500 --> 00:29:14,860 -We're going to need the -environment to do some more - -557 -00:29:14,860 --> 00:29:15,800 -evaluations. - -558 -00:29:15,800 --> 00:29:18,420 -We're going to need UNEV to look -at what the rest of those - -559 -00:29:18,420 --> 00:29:20,340 -arguments were. - -560 -00:29:20,340 --> 00:29:22,170 -We're going to assign continue -a place called - -561 -00:29:22,170 --> 00:29:24,040 -accumulate-args, or -accumulate-arg. - -562 -00:29:24,040 --> 00:29:30,898 - - -563 -00:29:30,898 --> 00:29:33,300 -OK, now, we've set up -for another call to - -564 -00:29:33,300 --> 00:29:36,810 -eval-dispatch, OK? - -565 -00:29:36,810 --> 00:29:39,510 -All right, now, let me -short-circuit this so we don't - -566 -00:29:39,510 --> 00:29:41,090 -go through the details -of eval-dispatch. - -567 -00:29:41,090 --> 00:29:45,550 -Eval-dispatch's contract says -I'm going to end up, the world - -568 -00:29:45,550 --> 00:29:48,480 -will end up, with the value of -evaluating this expression in - -569 -00:29:48,480 --> 00:29:50,270 -this environment in -the VAL register, - -570 -00:29:50,270 --> 00:29:51,320 -and I'll end up there. - -571 -00:29:51,320 --> 00:29:58,010 -So we short-circuit all of this, -and a 3 ends up in VAL. - -572 -00:29:58,010 --> 00:30:00,050 -And, when we return from -eval-dispatch, we're going to - -573 -00:30:00,050 --> 00:30:02,110 -return to accumulate-arg. - -574 -00:30:02,110 --> 00:30:03,555 -PROFESSOR: Accumulate-arg. - -575 -00:30:03,555 --> 00:30:08,720 -PROFESSOR: With 3 in the -VAL register, OK? - -576 -00:30:08,720 --> 00:30:10,650 -So that short-circuited -that evaluation. - -577 -00:30:10,650 --> 00:30:11,320 -Now, what do we do? - -578 -00:30:11,320 --> 00:30:13,230 -We're going to go back and -look at the rest of the - -579 -00:30:13,230 --> 00:30:18,580 -arguments, so we restore -UNEV. We restore - -580 -00:30:18,580 --> 00:30:28,650 -ENV. We restore argl. - -581 -00:30:28,650 --> 00:30:29,170 -One thing. - -582 -00:30:29,170 --> 00:30:30,750 -PROFESSOR: Oops! - -583 -00:30:30,750 --> 00:30:31,290 -Parity error. - -584 -00:30:31,290 --> 00:30:33,465 -[LAUGHTER] - -585 -00:30:33,465 --> 00:30:34,905 -PROFESSOR: Restore argl. - -586 -00:30:34,905 --> 00:30:41,650 - - -587 -00:30:41,650 --> 00:30:42,900 -PROFESSOR: OK. - -588 -00:30:42,900 --> 00:30:45,570 - - -589 -00:30:45,570 --> 00:30:51,880 -OK, we assign to argl consing on -fetch of the value register - -590 -00:30:51,880 --> 00:30:53,130 -to what's in argl. - -591 -00:30:53,130 --> 00:30:58,985 - - -592 -00:30:58,985 --> 00:31:04,050 -OK, we assign to UNEV the rest -of the operands in fetch of - -593 -00:31:04,050 --> 00:31:11,516 -UNEV, and we go back -to eval-arg-loop. - -594 -00:31:11,516 --> 00:31:12,280 -PROFESSOR: Eval-arg-loop. - -595 -00:31:12,280 --> 00:31:13,530 -PROFESSOR: OK. - -596 -00:31:13,530 --> 00:31:15,880 - - -597 -00:31:15,880 --> 00:31:18,090 -Now, we're about to do the next -argument, so the first - -598 -00:31:18,090 --> 00:31:19,340 -thing we do is save argl. - -599 -00:31:19,340 --> 00:31:25,400 - - -600 -00:31:25,400 --> 00:31:35,060 -OK, we assign to x the first -operand of fetch of UNEV. OK, - -601 -00:31:35,060 --> 00:31:37,140 -we test and see if that's -the last operand. - -602 -00:31:37,140 --> 00:31:40,320 -In this case, it is, so we're -going to go to a special place - -603 -00:31:40,320 --> 00:31:43,930 -that says evaluate the last -argument because, notice, - -604 -00:31:43,930 --> 00:31:45,600 -after evaluating the argument, -we don't need the - -605 -00:31:45,600 --> 00:31:47,446 -environment any more. - -606 -00:31:47,446 --> 00:31:50,250 -That's going to be -the difference. - -607 -00:31:50,250 --> 00:31:53,090 -So here, at eval-last-arg, -which is assigned to - -608 -00:31:53,090 --> 00:32:06,220 -accumulate-last-arg, now, -we're set up again for - -609 -00:32:06,220 --> 00:32:06,900 -eval-dispatch. - -610 -00:32:06,900 --> 00:32:08,620 -We've got a place to go -to when we're done. - -611 -00:32:08,620 --> 00:32:09,840 -We've got an expression. - -612 -00:32:09,840 --> 00:32:11,330 -We've got an environment. - -613 -00:32:11,330 --> 00:32:14,370 -OK, so we'll short-circuit the -call to eval-dispatch. - -614 -00:32:14,370 --> 00:32:18,090 -And what'll happen is there's -a y there, it's 4 in that - -615 -00:32:18,090 --> 00:32:21,060 -environment, so VAL will -end up with 4 in it. - -616 -00:32:21,060 --> 00:32:25,450 -And, then, we're going to end up -at accumulate-last-arg, OK? - -617 -00:32:25,450 --> 00:32:30,150 -So, at accumulate-last-arg, -we restore argl. - -618 -00:32:30,150 --> 00:32:41,490 - - -619 -00:32:41,490 --> 00:32:45,460 -We assign to argl cons of fetch -of the new value onto - -620 -00:32:45,460 --> 00:32:49,850 -it, so we cons a 4 onto that. - -621 -00:32:49,850 --> 00:32:53,446 -We restore what was saved in -the function register. - -622 -00:32:53,446 --> 00:32:56,590 -And notice, in this case, it had -not been destroyed, but, - -623 -00:32:56,590 --> 00:32:59,420 -in general, it will be. - -624 -00:32:59,420 --> 00:33:02,850 -And now, we're ready to go off -to apply-dispatch, all right? - -625 -00:33:02,850 --> 00:33:04,510 -So we've just gone -through the eval. - -626 -00:33:04,510 --> 00:33:07,980 -We evaluated the argument, the -operator, and the arguments, - -627 -00:33:07,980 --> 00:33:09,580 -and now, we're about -to apply them. - -628 -00:33:09,580 --> 00:33:17,481 -So we come off to apply-dispatch -here, OK? - -629 -00:33:17,481 --> 00:33:21,670 -We come off to apply-dispatch, -and we're going to check - -630 -00:33:21,670 --> 00:33:23,450 -whether it's a primitive or -a compound procedure. - -631 -00:33:23,450 --> 00:33:24,116 -PROFESSOR: Yes. - -632 -00:33:24,116 --> 00:33:24,830 -PROFESSOR: All right. - -633 -00:33:24,830 --> 00:33:27,870 -So, in this case, it's a -primitive procedure, and we go - -634 -00:33:27,870 --> 00:33:29,790 -off to primitive-apply. - -635 -00:33:29,790 --> 00:33:34,130 -So we go off to primitive-apply, -and it says - -636 -00:33:34,130 --> 00:33:38,360 -assign to VAL the result of -applying primitive procedure - -637 -00:33:38,360 --> 00:33:40,940 -of the function to the -argument list. - -638 -00:33:40,940 --> 00:33:42,540 -PROFESSOR: I don't -know how to add. - -639 -00:33:42,540 --> 00:33:43,995 -I'm just an execution unit. - -640 -00:33:43,995 --> 00:33:45,350 -PROFESSOR: Well, I don't -know how to add either. - -641 -00:33:45,350 --> 00:33:48,360 -I'm just the evaluator, so we -need a primitive operator. - -642 -00:33:48,360 --> 00:33:51,290 -Let's see, so the primitive -operator, what's the - -643 -00:33:51,290 --> 00:33:52,605 -sum of 3 and 4? - -644 -00:33:52,605 --> 00:33:53,205 -AUDIENCE: 7. - -645 -00:33:53,205 --> 00:33:54,580 -PROFESSOR: OK, 7. - -646 -00:33:54,580 --> 00:33:55,999 -PROFESSOR: Thank you. - -647 -00:33:55,999 --> 00:33:58,837 - - -648 -00:33:58,837 --> 00:34:12,330 -PROFESSOR: Now, we restore -continue, and we go to fetch - -649 -00:34:12,330 --> 00:34:12,900 -of continue. - -650 -00:34:12,900 --> 00:34:13,880 -PROFESSOR: Done. - -651 -00:34:13,880 --> 00:34:14,929 -PROFESSOR: OK. - -652 -00:34:14,929 --> 00:34:18,659 -Well, that was in as much detail -as you will ever see. - -653 -00:34:18,659 --> 00:34:21,590 -We'll never do it in as -much detail again. - -654 -00:34:21,590 --> 00:34:25,780 -One very important thing to -notice is that we just - -655 -00:34:25,780 --> 00:34:29,780 -executed a recursive -procedure, right? - -656 -00:34:29,780 --> 00:34:31,500 -This whole thing, we used -a stack and the - -657 -00:34:31,500 --> 00:34:33,070 -evaluator was recursive. - -658 -00:34:33,070 --> 00:34:36,480 -A lot of people think the reason -that you need a stack - -659 -00:34:36,480 --> 00:34:39,090 -and recursion in an evaluator -is because you might be - -660 -00:34:39,090 --> 00:34:40,810 -evaluating recursive -procedures like - -661 -00:34:40,810 --> 00:34:42,150 -factorial or Fibonacci. - -662 -00:34:42,150 --> 00:34:43,670 -It's not true. - -663 -00:34:43,670 --> 00:34:46,110 -So you notice we did recursion -here, and all we evaluated was - -664 -00:34:46,110 --> 00:34:48,010 -plus X, Y, all right? - -665 -00:34:48,010 --> 00:34:51,219 -The reason that you need -recursion in the evaluator is - -666 -00:34:51,219 --> 00:34:53,550 -because the evaluation -process, itself, is - -667 -00:34:53,550 --> 00:34:54,780 -recursive, all right? - -668 -00:34:54,780 --> 00:34:57,760 -It's not because the procedure -that you might be evaluating - -669 -00:34:57,760 --> 00:34:59,270 -in LISP is a recursive -procedure. - -670 -00:34:59,270 --> 00:35:01,130 -So that's an important -thing that people get - -671 -00:35:01,130 --> 00:35:03,010 -confused about a lot. - -672 -00:35:03,010 --> 00:35:06,280 -The other thing to notice is -that, when we're done here, - -673 -00:35:06,280 --> 00:35:07,120 -we're really done. - -674 -00:35:07,120 --> 00:35:12,600 -Not only are we at done, but -there's no accumulated stuff - -675 -00:35:12,600 --> 00:35:13,810 -on the stack, right? - -676 -00:35:13,810 --> 00:35:17,170 -The machine is back to its -initial state, all right? - -677 -00:35:17,170 --> 00:35:19,830 -So that's part of what -it means to be done. - -678 -00:35:19,830 --> 00:35:26,410 -Another way to say that is the -evaluation process has reduced - -679 -00:35:26,410 --> 00:35:33,460 -the expression, plus X, Y, -to the value here, 7. - -680 -00:35:33,460 --> 00:35:36,010 -And by reduced, I mean a -very particular thing. - -681 -00:35:36,010 --> 00:35:38,180 -It means that there's nothing -left on the stack. - -682 -00:35:38,180 --> 00:35:41,480 -The machine is now in the same -state, except there's - -683 -00:35:41,480 --> 00:35:42,760 -something in the -value register. - -684 -00:35:42,760 --> 00:35:44,520 -It's not part of a sub-problem -of anything. - -685 -00:35:44,520 --> 00:35:46,210 -There's nothing to go back to. - -686 -00:35:46,210 --> 00:35:46,440 -OK. - -687 -00:35:46,440 --> 00:35:47,690 -Let's break. - -688 -00:35:47,690 --> 00:35:49,712 - - -689 -00:35:49,712 --> 00:35:50,159 -Question? - -690 -00:35:50,159 --> 00:35:54,800 -AUDIENCE: The question here, in -the stack, is because the - -691 -00:35:54,800 --> 00:35:55,820 -data may be recursive. - -692 -00:35:55,820 --> 00:35:59,312 -You may have embedded -expressions, for instance. - -693 -00:35:59,312 --> 00:36:01,490 -PROFESSOR: Yes, because you -might have embedded - -694 -00:36:01,490 --> 00:36:02,080 -expressions. - -695 -00:36:02,080 --> 00:36:06,400 -But, again, don't confuse that -with what people sometimes - -696 -00:36:06,400 --> 00:36:08,660 -mean by the data may be -recursive, which is to say you - -697 -00:36:08,660 --> 00:36:12,270 -have these list-structured, -recursive data list - -698 -00:36:12,270 --> 00:36:12,930 -operations. - -699 -00:36:12,930 --> 00:36:13,980 -That has nothing -to do with it. - -700 -00:36:13,980 --> 00:36:15,360 -It's simply that the -expressions contain - -701 -00:36:15,360 --> 00:36:17,363 -sub-expressions. - -702 -00:36:17,363 --> 00:36:19,618 -Yeah? - -703 -00:36:19,618 --> 00:36:22,260 -AUDIENCE: Why is it that the -order of the arguments in the - -704 -00:36:22,260 --> 00:36:23,225 -arg list got reversed? - -705 -00:36:23,225 --> 00:36:23,860 -PROFESSOR: Ah! - -706 -00:36:23,860 --> 00:36:27,260 -Yes, I should've -mentioned that. - -707 -00:36:27,260 --> 00:36:28,755 -Here, the reason the -order is reversed-- - -708 -00:36:28,755 --> 00:36:32,507 - - -709 -00:36:32,507 --> 00:36:36,050 -it's a question of what -you mean by reversed. - -710 -00:36:36,050 --> 00:36:40,624 -I believe it was Newton. - -711 -00:36:40,624 --> 00:36:43,800 -In the very early part of -optics, people realized that, - -712 -00:36:43,800 --> 00:36:46,100 -when you look through the lens -of your eye, the image was - -713 -00:36:46,100 --> 00:36:46,840 -up-side down. - -714 -00:36:46,840 --> 00:36:48,650 -And there was a lot of argument -about why that didn't - -715 -00:36:48,650 --> 00:36:51,280 -mean you saw things -up-side down. - -716 -00:36:51,280 --> 00:36:52,860 -So it's sort of the -same issue. - -717 -00:36:52,860 --> 00:36:54,810 -Reversed from what? - -718 -00:36:54,810 --> 00:36:57,940 -So we just need some -convention. - -719 -00:36:57,940 --> 00:37:01,730 -The reason that they're coming -at 4, 3 is because we're - -720 -00:37:01,730 --> 00:37:04,520 -taking UNEV and consing -the result onto argl. - -721 -00:37:04,520 --> 00:37:06,900 -So you have to realize you've -made that convention. - -722 -00:37:06,900 --> 00:37:10,100 -The place that you have -to realize that-- - -723 -00:37:10,100 --> 00:37:11,230 -well, there's actually -two places. - -724 -00:37:11,230 --> 00:37:12,910 -One is in -apply-primitive-operator, - -725 -00:37:12,910 --> 00:37:16,610 -which has to realize that the -arguments to primitives go in, - -726 -00:37:16,610 --> 00:37:19,490 -in the opposite order from the -way you're writing them down. - -727 -00:37:19,490 --> 00:37:21,760 -And the other one is, we'll see -later when you actually go - -728 -00:37:21,760 --> 00:37:24,720 -to bind a function's parameters, -you should realize - -729 -00:37:24,720 --> 00:37:26,410 -the arguments are going to -come in from the opposite - -730 -00:37:26,410 --> 00:37:28,870 -order of the variables to which -you're binding them. - -731 -00:37:28,870 --> 00:37:31,830 -So, if you just keep track of -that, there's no problem. - -732 -00:37:31,830 --> 00:37:34,560 -Also, this is completely -arbitrary because, if we'd - -733 -00:37:34,560 --> 00:37:36,890 -done, say, an iteration through -a vector assigning - -734 -00:37:36,890 --> 00:37:40,730 -them, they might come out -in the other order, OK? - -735 -00:37:40,730 --> 00:37:42,700 -So it's just a convention of -the way this particular - -736 -00:37:42,700 --> 00:37:45,085 -evaluator works. - -737 -00:37:45,085 --> 00:37:46,335 -All right, let's take a break. - -738 -00:37:46,335 --> 00:38:41,840 - - -739 -00:38:41,840 --> 00:38:46,050 -We just saw evaluating an -expression and, of course, - -740 -00:38:46,050 --> 00:38:46,950 -that was very simple one. - -741 -00:38:46,950 --> 00:38:51,020 -But, in essence, it would be -no different if it was some - -742 -00:38:51,020 --> 00:38:53,370 -big nested expression, so there -would just be deeper - -743 -00:38:53,370 --> 00:38:55,130 -recursion on the stack. - -744 -00:38:55,130 --> 00:38:56,920 -But what I want to do now is -show you the last piece. - -745 -00:38:56,920 --> 00:39:01,300 -I want to walk you around this -eval and apply loop, right? - -746 -00:39:01,300 --> 00:39:03,000 -That's the thing we haven't -seen, really. - -747 -00:39:03,000 --> 00:39:09,070 -We haven't seen any compound -procedures where applying a - -748 -00:39:09,070 --> 00:39:11,110 -procedure reduces to evaluating -the body of the - -749 -00:39:11,110 --> 00:39:15,810 -procedure, so let's just -suppose we had this. - -750 -00:39:15,810 --> 00:39:29,340 -Suppose we were looking at the -procedure define F of A and B - -751 -00:39:29,340 --> 00:39:36,520 -to be the sum of A and B. So, as -we typed in that procedure - -752 -00:39:36,520 --> 00:39:41,120 -previously, and now we're going -to evaluate F of X and - -753 -00:39:41,120 --> 00:39:46,030 -Y, again, in this environment, -E,0, where X is bound to 3 and - -754 -00:39:46,030 --> 00:39:47,280 -Y is bound to 4. - -755 -00:39:47,280 --> 00:39:50,830 - - -756 -00:39:50,830 --> 00:39:53,120 -When the defined is executed, -remember, there's a lambda - -757 -00:39:53,120 --> 00:39:55,950 -here, and lambdas create -procedures. - -758 -00:39:55,950 --> 00:40:01,430 -And, basically, what will happen -is, in E,0, we'll end - -759 -00:40:01,430 --> 00:40:07,440 -up with a binding for F, which -will say F is a procedure, and - -760 -00:40:07,440 --> 00:40:18,180 -its args are A and B, and -its body is plus a,b. - -761 -00:40:18,180 --> 00:40:21,460 -So that's what the environment -would have looked like had we - -762 -00:40:21,460 --> 00:40:24,400 -made that definition. - -763 -00:40:24,400 --> 00:40:29,180 -Then, when we go to evaluate F -of X and Y, we'll go through - -764 -00:40:29,180 --> 00:40:31,810 -exactly the same process -that we did before. - -765 -00:40:31,810 --> 00:40:33,360 -It's even the same expression. - -766 -00:40:33,360 --> 00:40:36,030 -The only difference is that F, -instead of having primitive - -767 -00:40:36,030 --> 00:40:41,040 -plus in it, will have -this thing. - -768 -00:40:41,040 --> 00:40:43,600 -And so we'll go through exactly -the same process, - -769 -00:40:43,600 --> 00:40:48,130 -except this time, when we end -up at apply-dispatch, the - -770 -00:40:48,130 --> 00:40:50,590 -function register, instead of -having primitive plus, will - -771 -00:40:50,590 --> 00:40:54,300 -have a thing that will represent -it saying procedure, - -772 -00:40:54,300 --> 00:41:08,040 -where the args are A and B, -and the body is plus A, B. - -773 -00:41:08,040 --> 00:41:10,420 -And, again, what I mean, by -its ENV, I mean there's a - -774 -00:41:10,420 --> 00:41:12,530 -pointer to it, so don't worry -that I'm writing a lot of - -775 -00:41:12,530 --> 00:41:13,280 -stuff there. - -776 -00:41:13,280 --> 00:41:17,170 -There's a pointer to this -procedure data structure. - -777 -00:41:17,170 --> 00:41:20,960 -OK, so, we're in exactly -the same situation. - -778 -00:41:20,960 --> 00:41:25,720 -We get to apply-dispatch, -so, here, we come to - -779 -00:41:25,720 --> 00:41:26,480 -apply-dispatch. - -780 -00:41:26,480 --> 00:41:30,010 -Last time, we branched off -to a primitive procedure. - -781 -00:41:30,010 --> 00:41:34,900 -Here, it says oh, we now have a -compound procedure, so we're - -782 -00:41:34,900 --> 00:41:36,150 -going to go off to -compound-apply. - -783 -00:41:36,150 --> 00:41:38,660 - - -784 -00:41:38,660 --> 00:41:39,910 -Now, what's compound-apply? - -785 -00:41:39,910 --> 00:41:42,100 - - -786 -00:41:42,100 --> 00:41:45,090 -Well, remember what the -meta-circular evaluator did? - -787 -00:41:45,090 --> 00:41:50,790 -Compound-apply said we're going -to evaluate the body of - -788 -00:41:50,790 --> 00:41:54,120 -the procedure in some -new environment. - -789 -00:41:54,120 --> 00:41:56,730 -Where does that new environment -come from? - -790 -00:41:56,730 --> 00:42:00,620 -We take the environment that -was packaged with the - -791 -00:42:00,620 --> 00:42:06,080 -procedure, we bind the -parameters of the procedure to - -792 -00:42:06,080 --> 00:42:10,760 -the arguments that we're passing -in, and use that as a - -793 -00:42:10,760 --> 00:42:14,990 -new frame to extend the -procedure environment. - -794 -00:42:14,990 --> 00:42:18,100 -And that's the environment -in which we evaluate the - -795 -00:42:18,100 --> 00:42:21,630 -procedure body, right? - -796 -00:42:21,630 --> 00:42:24,470 -That's going around the -apply/eval loop. - -797 -00:42:24,470 --> 00:42:27,988 -That's apply coming back to -call eval, all right? - -798 -00:42:27,988 --> 00:42:30,910 - - -799 -00:42:30,910 --> 00:42:32,860 -OK. - -800 -00:42:32,860 --> 00:42:36,950 -So, now, that's all we have -to do in compound-apply. - -801 -00:42:36,950 --> 00:42:37,720 -What are we going to do? - -802 -00:42:37,720 --> 00:42:40,730 -We're going to manufacture -a new environment. - -803 -00:42:40,730 --> 00:42:43,720 - - -804 -00:42:43,720 --> 00:42:47,060 -And we're going to manufacture -a new environment, let's see, - -805 -00:42:47,060 --> 00:42:48,310 -that we'll call E,1. - -806 -00:42:48,310 --> 00:42:53,100 - - -807 -00:42:53,100 --> 00:42:57,830 -E,1 is going to be some -environment where the - -808 -00:42:57,830 --> 00:43:02,460 -parameters of the procedure, -where A is bound to 3 and B is - -809 -00:43:02,460 --> 00:43:06,220 -bound to 4, and it's linked -to E,0 because - -810 -00:43:06,220 --> 00:43:09,270 -that's where f is defined. - -811 -00:43:09,270 --> 00:43:11,090 -And, in this environment, we're -going to evaluate the - -812 -00:43:11,090 --> 00:43:12,050 -body of the procedure. - -813 -00:43:12,050 --> 00:43:13,870 -So let's look at that, -all right? - -814 -00:43:13,870 --> 00:43:16,730 - - -815 -00:43:16,730 --> 00:43:20,690 -All right, here we are at -compound-apply, which says - -816 -00:43:20,690 --> 00:43:25,560 -assign to the expression -register the body of the - -817 -00:43:25,560 --> 00:43:28,300 -procedure that's in the -function register. - -818 -00:43:28,300 --> 00:43:31,470 -So I assign to the expression -register the - -819 -00:43:31,470 --> 00:43:42,710 -procedure body, OK? - -820 -00:43:42,710 --> 00:43:46,300 -That's going to be evaluated -in an environment which is - -821 -00:43:46,300 --> 00:43:53,040 -formed by making some bindings -using information determined - -822 -00:43:53,040 --> 00:43:53,860 -by the procedure-- - -823 -00:43:53,860 --> 00:43:55,320 -that's what's in FUN-- - -824 -00:43:55,320 --> 00:43:57,800 -and the argument list. - -825 -00:43:57,800 --> 00:44:00,230 -And let's not worry about -exactly what that does, but - -826 -00:44:00,230 --> 00:44:01,930 -you can see the information's -there. - -827 -00:44:01,930 --> 00:44:06,420 -So make bindings will say oh, -the procedure, itself, had an - -828 -00:44:06,420 --> 00:44:08,200 -environment attached to it. - -829 -00:44:08,200 --> 00:44:09,320 -I didn't write that -quite here. - -830 -00:44:09,320 --> 00:44:11,810 -I should've said in environment -because every - -831 -00:44:11,810 --> 00:44:13,660 -procedure gets built with -an environment. - -832 -00:44:13,660 --> 00:44:17,400 -So, from that environment, it -knows what the procedure's - -833 -00:44:17,400 --> 00:44:19,290 -definition environment is. - -834 -00:44:19,290 --> 00:44:21,830 -It knows what the -arguments are. - -835 -00:44:21,830 --> 00:44:23,060 -It looks at argl, and -then you see a - -836 -00:44:23,060 --> 00:44:24,280 -reversal convention here. - -837 -00:44:24,280 --> 00:44:27,830 -It just has to know that argl -is reversed, and it builds - -838 -00:44:27,830 --> 00:44:29,990 -this frame, E,1. - -839 -00:44:29,990 --> 00:44:32,400 -All right, so, let's assume that -that's what make bindings - -840 -00:44:32,400 --> 00:44:35,780 -returns, so it assigns to -ENV this thing, E,1. - -841 -00:44:35,780 --> 00:44:41,490 - - -842 -00:44:41,490 --> 00:44:46,890 -All right, the next thing it -says is restore continue. - -843 -00:44:46,890 --> 00:44:48,760 -Remember what continue -was here? - -844 -00:44:48,760 --> 00:44:52,240 -It got put up in the -last segment. - -845 -00:44:52,240 --> 00:44:54,020 -Continue got stored. - -846 -00:44:54,020 --> 00:44:56,180 -That was the original done, -which said what are you going - -847 -00:44:56,180 --> 00:44:59,920 -to do after you're done with -this particular application? - -848 -00:44:59,920 --> 00:45:01,980 -It was one of the very first -things that happened when we - -849 -00:45:01,980 --> 00:45:03,920 -evaluated the application. - -850 -00:45:03,920 --> 00:45:06,860 -And now, finally, we're going -to restore continue. - -851 -00:45:06,860 --> 00:45:09,290 -Remember apply-dispatch's -contract. - -852 -00:45:09,290 --> 00:45:11,570 -It assumes that where it should -go to next was on the - -853 -00:45:11,570 --> 00:45:13,590 -stack, and there it -was on the stack. - -854 -00:45:13,590 --> 00:45:19,310 -Continue has done, and now -we're going to go back to - -855 -00:45:19,310 --> 00:45:19,940 -eval-dispatch. - -856 -00:45:19,940 --> 00:45:20,970 -We're set up again. - -857 -00:45:20,970 --> 00:45:23,470 -We have an expression, -an environment, and - -858 -00:45:23,470 --> 00:45:25,511 -a place to go to. - -859 -00:45:25,511 --> 00:45:28,690 -We're not going to go through -that because it's sort of the - -860 -00:45:28,690 --> 00:45:29,940 -same expression. - -861 -00:45:29,940 --> 00:45:35,167 - - -862 -00:45:35,167 --> 00:45:39,590 -OK, but the thing, again, to -notice is, at this point, we - -863 -00:45:39,590 --> 00:45:44,830 -have reduced the original -expression, F,X,Y, right? - -864 -00:45:44,830 --> 00:45:50,150 -We've reduced evaluating F,X,Y -in environment E,0 to evaluate - -865 -00:45:50,150 --> 00:45:52,670 -plus A, B in E,1. - -866 -00:45:52,670 --> 00:45:55,720 -And notice, nothing's -on the stack, right? - -867 -00:45:55,720 --> 00:45:56,830 -It's a reduction. - -868 -00:45:56,830 --> 00:46:00,530 -At this point, the machine does -not contain, as part of - -869 -00:46:00,530 --> 00:46:03,790 -its state, the fact that it's -in the middle of evaluating - -870 -00:46:03,790 --> 00:46:08,090 -some procedure called f, -that's gone, right? - -871 -00:46:08,090 --> 00:46:13,072 -There's no accumulated -state, OK? - -872 -00:46:13,072 --> 00:46:14,370 -Again, that's a very -important idea. - -873 -00:46:14,370 --> 00:46:17,590 -That's the meaning of, when -we used to write in the - -874 -00:46:17,590 --> 00:46:20,430 -substitution model, this -expression reduces to that - -875 -00:46:20,430 --> 00:46:21,350 -expression. - -876 -00:46:21,350 --> 00:46:22,660 -And you don't have to -remember anything. - -877 -00:46:22,660 --> 00:46:24,500 -And here, you see the meaning -of reduction. - -878 -00:46:24,500 --> 00:46:26,160 -At this point, there is -nothing on the stack. - -879 -00:46:26,160 --> 00:46:31,590 - - -880 -00:46:31,590 --> 00:46:35,240 -See, that has very important -consequences. - -881 -00:46:35,240 --> 00:46:37,180 -Let's go back and look -at iterative - -882 -00:46:37,180 --> 00:46:40,590 -factorial, all right? - -883 -00:46:40,590 --> 00:46:45,130 -Remember, this was some sort -of loop and doing iter. - -884 -00:46:45,130 --> 00:46:49,430 -And we kept saying that's an -iterative procedure, right? - -885 -00:46:49,430 --> 00:46:52,570 - - -886 -00:46:52,570 --> 00:47:04,660 -And what we wrote, remember, -are things like, we said, - -887 -00:47:04,660 --> 00:47:12,360 -fact-iter of 5. - -888 -00:47:12,360 --> 00:47:19,030 -We wrote things like reduces -to iter of 1, and 1, and 5, - -889 -00:47:19,030 --> 00:47:26,550 -which reduces to iter of 1, and -2, and 5, and so on, and - -890 -00:47:26,550 --> 00:47:27,210 -so on, and so on. - -891 -00:47:27,210 --> 00:47:29,360 -And we kept saying well, look, -you don't have to build up any - -892 -00:47:29,360 --> 00:47:31,720 -storage to do that. - -893 -00:47:31,720 --> 00:47:33,730 -And we waved our hands, and said -in principle, there's no - -894 -00:47:33,730 --> 00:47:35,040 -storage needed. - -895 -00:47:35,040 --> 00:47:36,170 -Now, you see no storage -needed. - -896 -00:47:36,170 --> 00:47:39,090 -Each of these is a real -reduction, right? - -897 -00:47:39,090 --> 00:47:49,280 - - -898 -00:47:49,280 --> 00:47:51,370 -As you walk through these -expressions, what you'll see - -899 -00:47:51,370 --> 00:47:54,810 -are these expressions on the -stack in some particular - -900 -00:47:54,810 --> 00:48:00,045 -environment, and then these -expressions in the EXP - -901 -00:48:00,045 --> 00:48:01,650 -register in some particular -environment. - -902 -00:48:01,650 --> 00:48:03,570 -And, at each point, there'll be -no accumulated stuff on the - -903 -00:48:03,570 --> 00:48:09,135 -stack because each one's -a real reduction, OK? - -904 -00:48:09,135 --> 00:48:11,520 -All right, so, for example, -just to go through it in a - -905 -00:48:11,520 --> 00:48:15,510 -little bit more care, if I start -out with an expression - -906 -00:48:15,510 --> 00:48:33,520 -that says something like, oh, -say, fact-iter of 5 in some - -907 -00:48:33,520 --> 00:48:46,810 -environment that will, at some -point, create an environment - -908 -00:48:46,810 --> 00:48:48,120 -in which n is down to 5. - -909 -00:48:48,120 --> 00:48:51,340 - - -910 -00:48:51,340 --> 00:48:52,590 -Let's call that-- - -911 -00:48:52,590 --> 00:48:55,750 - - -912 -00:48:55,750 --> 00:49:02,120 -And, at some point, the machine -will reduce this whole - -913 -00:49:02,120 --> 00:49:08,780 -thing to a thing that says -that's really iter of 1, and - -914 -00:49:08,780 --> 00:49:16,550 -1, and n, evaluated in this -environment, E,1 with nothing - -915 -00:49:16,550 --> 00:49:17,160 -on the stack. - -916 -00:49:17,160 --> 00:49:20,710 -See, at this moment, the machine -is not remembering - -917 -00:49:20,710 --> 00:49:22,500 -that evaluating this -expression, iter-- - -918 -00:49:22,500 --> 00:49:25,000 - - -919 -00:49:25,000 --> 00:49:27,280 -which is the loop-- is -part of this thing - -920 -00:49:27,280 --> 00:49:29,366 -called iterative factorial. - -921 -00:49:29,366 --> 00:49:30,590 -It's not remembering that. - -922 -00:49:30,590 --> 00:49:33,170 -It's just reducing the -expression to that, right? - -923 -00:49:33,170 --> 00:49:38,390 -If we look again at the body of -iterative factorial, this - -924 -00:49:38,390 --> 00:49:42,810 -expression has reduced -to that expression. - -925 -00:49:42,810 --> 00:49:44,060 -Oh, I shouldn't have -the n there. - -926 -00:49:44,060 --> 00:49:46,590 - - -927 -00:49:46,590 --> 00:49:48,495 -It's a slightly different -convention from the slide to - -928 -00:49:48,495 --> 00:49:53,340 -the program, OK? - -929 -00:49:53,340 --> 00:49:56,310 -And, then, what's the -body of iter? - -930 -00:49:56,310 --> 00:49:59,460 -Well, iter's going to be an it, -and I won't go through the - -931 -00:49:59,460 --> 00:50:00,060 -details of if. - -932 -00:50:00,060 --> 00:50:02,540 -It'll evaluate the predicate. - -933 -00:50:02,540 --> 00:50:03,810 -In this case, it'll be false. - -934 -00:50:03,810 --> 00:50:14,490 -And this iter will now reduce -to the expression iter of - -935 -00:50:14,490 --> 00:50:21,620 -whatever it says, star, -counter product, and-- - -936 -00:50:21,620 --> 00:50:22,650 -what does it say-- - -937 -00:50:22,650 --> 00:50:30,820 -plus counter 1 in some other -environment, by this time, - -938 -00:50:30,820 --> 00:50:38,840 -E,2, where E,2 will be set up -having bindings for product - -939 -00:50:38,840 --> 00:50:43,200 -and counter, right? - -940 -00:50:43,200 --> 00:50:45,140 -And it'll reduce -to that, right? - -941 -00:50:45,140 --> 00:50:47,925 -It won't be remembering that -it's part of something that it - -942 -00:50:47,925 --> 00:50:49,340 -has to return to. - -943 -00:50:49,340 --> 00:50:51,500 -And when iter calls iter again, -it'll reduce to another - -944 -00:50:51,500 --> 00:50:55,050 -thing that looks like this in -some environment, E,3, which - -945 -00:50:55,050 --> 00:50:59,160 -has new bindings for product -and counter. - -946 -00:50:59,160 --> 00:51:08,450 -So, if you're wondering, see, -if you've always been queasy - -947 -00:51:08,450 --> 00:51:10,920 -about how it is we've been -saying those procedures, that - -948 -00:51:10,920 --> 00:51:16,095 -look syntactically recursive, -are, in fact, iterative, run - -949 -00:51:16,095 --> 00:51:19,230 -in constant space, well, I don't -know if this makes you - -950 -00:51:19,230 --> 00:51:21,230 -less queasy, but at least it -shows you what's happening. - -951 -00:51:21,230 --> 00:51:22,830 -There really isn't any -buildup there. - -952 -00:51:22,830 --> 00:51:25,910 - - -953 -00:51:25,910 --> 00:51:28,830 -Now, you might ask well, is -there buildup in principle in - -954 -00:51:28,830 --> 00:51:31,710 -these environment frames? - -955 -00:51:31,710 --> 00:51:33,240 -And the answer is yeah, you -have to make these new - -956 -00:51:33,240 --> 00:51:35,560 -environment frames, but you -don't have to hang onto them - -957 -00:51:35,560 --> 00:51:36,440 -when you're done. - -958 -00:51:36,440 --> 00:51:39,020 -They can be garbage collected, -or the space can be reused - -959 -00:51:39,020 --> 00:51:40,720 -automatically. - -960 -00:51:40,720 --> 00:51:43,520 -But you see the control -structure of the evaluator is - -961 -00:51:43,520 --> 00:51:47,020 -really using this idea that you -actually have a reduction, - -962 -00:51:47,020 --> 00:51:50,132 -so these procedures really -are iterative procedures. - -963 -00:51:50,132 --> 00:51:51,382 -All right, let's stop -for questions. - -964 -00:51:51,382 --> 00:52:02,288 - - -965 -00:52:02,288 --> 00:52:03,538 -All right, let's break. - -966 -00:52:03,538 --> 00:52:48,770 - - -967 -00:52:48,770 --> 00:52:53,470 -Let me contrast the iterative -procedure just so you'll see - -968 -00:52:53,470 --> 00:52:56,480 -where space does build up with -a recursive procedure, so you - -969 -00:52:56,480 --> 00:52:58,030 -can see the difference. - -970 -00:52:58,030 --> 00:53:00,470 -Let's look at the evaluation -of recursive - -971 -00:53:00,470 --> 00:53:02,880 -factorial, all right? - -972 -00:53:02,880 --> 00:53:07,220 -So, here's fact-recursive, or -standard factorial definition. - -973 -00:53:07,220 --> 00:53:10,360 -We said this one is still a -recursive procedure, but this - -974 -00:53:10,360 --> 00:53:13,750 -is actually a recursive -process. - -975 -00:53:13,750 --> 00:53:17,210 -And then, just to link it back -to the way we started, we said - -976 -00:53:17,210 --> 00:53:20,530 -oh, you can see that it's going -to be recursive process - -977 -00:53:20,530 --> 00:53:24,520 -by the substitution model -because, if I say recursive - -978 -00:53:24,520 --> 00:53:36,000 -factorial of 5, that turns -into 5 times-- - -979 -00:53:36,000 --> 00:53:37,989 -what is it, fact-rec, -or record fact-- - -980 -00:53:37,989 --> 00:53:42,620 - - -981 -00:53:42,620 --> 00:53:54,230 -5 times recursive factorial of -4, which turns into 5 times 4 - -982 -00:53:54,230 --> 00:54:08,090 -times fact-rec of 3, which -returns into 5 times 4 times 3 - -983 -00:54:08,090 --> 00:54:15,240 -times, and so on, right? - -984 -00:54:15,240 --> 00:54:18,100 -The idea is there was this chain -of stuff building up, - -985 -00:54:18,100 --> 00:54:20,540 -which justified, in the -substitution model, the fact - -986 -00:54:20,540 --> 00:54:21,520 -that it's recursive. - -987 -00:54:21,520 --> 00:54:24,180 -And now, let's actually see that -chain of stuff build up - -988 -00:54:24,180 --> 00:54:27,465 -and where it is in -the machine, OK? - -989 -00:54:27,465 --> 00:54:28,970 -All right, well, let's -imagine we're going - -990 -00:54:28,970 --> 00:54:30,230 -to start out again. - -991 -00:54:30,230 --> 00:54:41,690 -We'll tell it to evaluate -recursive factorial of 5 in - -992 -00:54:41,690 --> 00:54:46,360 -some environment, again, E,0 -where recursive factorial is - -993 -00:54:46,360 --> 00:54:49,580 -defined, OK? - -994 -00:54:49,580 --> 00:54:52,490 -Well, now we know what's -eventually going to happen. - -995 -00:54:52,490 --> 00:54:55,670 -This is going to come along, -it'll evaluate those things, - -996 -00:54:55,670 --> 00:54:58,860 -figure out it's a procedure, -build somewhere over here an - -997 -00:54:58,860 --> 00:55:05,860 -environment, E,1, which has n -bound to 5, which hangs off of - -998 -00:55:05,860 --> 00:55:09,620 -E,0, which would be, presumably, -the definition - -999 -00:55:09,620 --> 00:55:14,610 -environment of recursive -factorial, OK? - -1000 -00:55:14,610 --> 00:55:16,490 -And, in this environment, -it's going to go off and - -1001 -00:55:16,490 --> 00:55:19,670 -evaluate the body. - -1002 -00:55:19,670 --> 00:55:27,860 -So, again, the evaluation here -will reduce to evaluating the - -1003 -00:55:27,860 --> 00:55:30,240 -body in E,1. - -1004 -00:55:30,240 --> 00:55:32,880 -That's going to look at an if, -and I won't go through the - -1005 -00:55:32,880 --> 00:55:33,530 -details of if. - -1006 -00:55:33,530 --> 00:55:34,880 -It'll look at the predicate. - -1007 -00:55:34,880 --> 00:55:37,840 -It'll decide it eventually has -to evaluate the alternative. - -1008 -00:55:37,840 --> 00:55:43,122 -So this whole thing, again, will -reduce to the alternative - -1009 -00:55:43,122 --> 00:55:47,870 -of recursive factorial, the -alternative clause, which says - -1010 -00:55:47,870 --> 00:55:56,040 -that this whole thing reduces -to times n of recursive - -1011 -00:55:56,040 --> 00:56:08,720 -factorial of n minus 1 in -the environment E,1, OK? - -1012 -00:56:08,720 --> 00:56:11,200 -So the original expression, -now, is going to reduce to - -1013 -00:56:11,200 --> 00:56:14,130 -evaluating that expression, -all right? - -1014 -00:56:14,130 --> 00:56:16,280 -Now we have an application. - -1015 -00:56:16,280 --> 00:56:18,500 -We did an application before. - -1016 -00:56:18,500 --> 00:56:20,390 -Remember what happens -in an application? - -1017 -00:56:20,390 --> 00:56:23,230 -The first thing you do is you go -off and you save the value - -1018 -00:56:23,230 --> 00:56:25,350 -of the continue register -on the stack. - -1019 -00:56:25,350 --> 00:56:27,365 -So the stack here is going -to have done in it. - -1020 -00:56:27,365 --> 00:56:29,980 - - -1021 -00:56:29,980 --> 00:56:32,230 -And then you're going to -set up to evaluate - -1022 -00:56:32,230 --> 00:56:35,130 -the sub-parts, OK? - -1023 -00:56:35,130 --> 00:56:36,710 -So here we go off to evaluate -the sub-parts. - -1024 -00:56:36,710 --> 00:56:39,520 - - -1025 -00:56:39,520 --> 00:56:41,045 -First thing we're going to do -is evaluate the operator. - -1026 -00:56:41,045 --> 00:56:44,490 - - -1027 -00:56:44,490 --> 00:56:47,250 -What happens when we evaluate -an operator? - -1028 -00:56:47,250 --> 00:56:49,940 -Well, we arrange things so that -the operator ends up in - -1029 -00:56:49,940 --> 00:56:51,480 -the expression register. - -1030 -00:56:51,480 --> 00:56:54,630 -The environments in the ENV -register continue someplace - -1031 -00:56:54,630 --> 00:56:56,590 -where we're going to go evaluate -the arguments. - -1032 -00:56:56,590 --> 00:56:59,520 -And, on the stack, we've saved -the original continue, which - -1033 -00:56:59,520 --> 00:57:01,720 -is where we wanted to be -when we're all done. - -1034 -00:57:01,720 --> 00:57:04,510 -And then the things we needed -when we're going to get done - -1035 -00:57:04,510 --> 00:57:07,190 -evaluating the operator, the -things we'll need to evaluate - -1036 -00:57:07,190 --> 00:57:11,710 -the arguments, namely, the -environment and those - -1037 -00:57:11,710 --> 00:57:14,790 -arguments, those unevaluated -arguments, so there they are - -1038 -00:57:14,790 --> 00:57:15,620 -sitting on the stack. - -1039 -00:57:15,620 --> 00:57:18,370 -And we're about to go off to -evaluate the operator. - -1040 -00:57:18,370 --> 00:57:23,130 - - -1041 -00:57:23,130 --> 00:57:26,920 -Well, when we return from -this particular call-- - -1042 -00:57:26,920 --> 00:57:29,380 -so we're about to call -eval-dispatch here-- - -1043 -00:57:29,380 --> 00:57:32,730 -when we return from this call, -the value of that operator, - -1044 -00:57:32,730 --> 00:57:34,890 -which, in this case, is going to -be the primitive multiplier - -1045 -00:57:34,890 --> 00:57:43,080 -procedure, will end up in the -FUN register, all right? - -1046 -00:57:43,080 --> 00:57:44,530 -We're going to evaluate -some arguments. - -1047 -00:57:44,530 --> 00:57:47,730 -They will evaluate in here. - -1048 -00:57:47,730 --> 00:57:50,250 -That'll give us 5, -in this case. - -1049 -00:57:50,250 --> 00:57:53,480 -We're going to put that in the -argl register, and then we'll - -1050 -00:57:53,480 --> 00:57:57,460 -go off to evaluate the -second operand. - -1051 -00:57:57,460 --> 00:58:00,050 -So, at the point where we go -off to evaluate the second - -1052 -00:58:00,050 --> 00:58:02,390 -operand-- and I'll skip details -like computing, and - -1053 -00:58:02,390 --> 00:58:04,510 -minus 1, and all of that-- -but, when we go off to - -1054 -00:58:04,510 --> 00:58:08,210 -evaluate the second operand, -that will eventually reduce to - -1055 -00:58:08,210 --> 00:58:09,460 -another call to fact-recursive. - -1056 -00:58:09,460 --> 00:58:12,060 - - -1057 -00:58:12,060 --> 00:58:17,520 -And, what we've got on the stack -here is the operator - -1058 -00:58:17,520 --> 00:58:20,290 -from that combination that we're -going to use it in and - -1059 -00:58:20,290 --> 00:58:23,790 -the other argument, OK? - -1060 -00:58:23,790 --> 00:58:28,490 -So, now, we're set up -for another call - -1061 -00:58:28,490 --> 00:58:30,200 -to recursive factorial. - -1062 -00:58:30,200 --> 00:58:32,300 -And, when we're done with this -one, we're going to go to - -1063 -00:58:32,300 --> 00:58:33,935 -accumulate the last arg. - -1064 -00:58:33,935 --> 00:58:35,200 -And remember what that'll do? - -1065 -00:58:35,200 --> 00:58:38,290 -That'll say oh, whatever the -result of this has to get - -1066 -00:58:38,290 --> 00:58:41,690 -combined with that, and we're -going to multiply them. - -1067 -00:58:41,690 --> 00:58:45,720 -But, notice now, we're at -another recursive factorial. - -1068 -00:58:45,720 --> 00:58:49,710 -We're about to call -eval-dispatch again, except we - -1069 -00:58:49,710 --> 00:58:51,250 -haven't really reduced it -because there's stuff - -1070 -00:58:51,250 --> 00:58:53,700 -on the stack now. - -1071 -00:58:53,700 --> 00:58:55,490 -The stuff on the stack says oh, -when you get back, you'd - -1072 -00:58:55,490 --> 00:58:58,430 -better multiply it by the -5 you had hanging there. - -1073 -00:58:58,430 --> 00:59:07,430 -So, when we go off to make -another call, we - -1074 -00:59:07,430 --> 00:59:09,300 -evaluate the n minus 1. - -1075 -00:59:09,300 --> 00:59:12,050 -That gives us another -environment in which the new - -1076 -00:59:12,050 --> 00:59:14,600 -n's going to be down to 4. - -1077 -00:59:14,600 --> 00:59:18,930 -And we're about to call -eval-dispatch again, right? - -1078 -00:59:18,930 --> 00:59:21,350 -We get another call. - -1079 -00:59:21,350 --> 00:59:26,040 -That 4 is going to end up -in the same situation. - -1080 -00:59:26,040 --> 00:59:30,020 -We'll end up with another call -to fact-recursive n. - -1081 -00:59:30,020 --> 00:59:32,330 -And sitting on the stack will be -the stuff from the original - -1082 -00:59:32,330 --> 00:59:35,360 -one and, now, the subsidiary -one we're doing. - -1083 -00:59:35,360 --> 00:59:36,910 -And both of them are waiting -for the same thing. - -1084 -00:59:36,910 --> 00:59:40,600 -They're going to go to -accumulate a last argument. - -1085 -00:59:40,600 --> 00:59:43,480 -And then, of course, when we -go to the fourth call, the - -1086 -00:59:43,480 --> 00:59:45,640 -same thing happens, right? - -1087 -00:59:45,640 --> 00:59:47,300 -And this goes on, -and on, and on. - -1088 -00:59:47,300 --> 00:59:51,430 -And what you see here on the -stack, exactly what's sitting - -1089 -00:59:51,430 --> 00:59:54,960 -here on the stack, the thing -that says times and 5. - -1090 -00:59:54,960 --> 00:59:57,490 -And what you're going to do with -that is accumulate that - -1091 -00:59:57,490 --> 01:00:00,470 -into a last argument. - -1092 -01:00:00,470 --> 01:00:02,760 -That's exactly this, right? - -1093 -01:00:02,760 --> 01:00:05,650 -This is exactly where that -stuff is hanging. - -1094 -01:00:05,650 --> 01:00:12,650 -Effectively, the operator you're -going to apply, the - -1095 -01:00:12,650 --> 01:00:15,300 -other argument that it's got to -be multiplied by when you - -1096 -01:00:15,300 --> 01:00:17,620 -get back and the parentheses, -which says yeah, what you - -1097 -01:00:17,620 --> 01:00:19,620 -wanted to do was accumulate -them. - -1098 -01:00:19,620 --> 01:00:22,560 -So, you see, the substitution -model is not such a lie. - -1099 -01:00:22,560 --> 01:00:24,460 -That really is, in some -sense, what's sitting - -1100 -01:00:24,460 --> 01:00:27,198 -right on the stack. - -1101 -01:00:27,198 --> 01:00:29,046 -OK. - -1102 -01:00:29,046 --> 01:00:33,260 -All right, so that, in some -sense, should explain for you, - -1103 -01:00:33,260 --> 01:00:37,850 -or at least convince you, that, -somehow, this evaluator - -1104 -01:00:37,850 --> 01:00:41,870 -is managing to take these -procedures and execute some of - -1105 -01:00:41,870 --> 01:00:46,410 -them iteratively and some of -them recursively, even though, - -1106 -01:00:46,410 --> 01:00:49,430 -as syntactically, they look -like recursive procedures. - -1107 -01:00:49,430 --> 01:00:50,660 -How's it managing to do that? - -1108 -01:00:50,660 --> 01:00:54,090 -Well, the basic reason it's -managing to do that is the - -1109 -01:00:54,090 --> 01:01:01,090 -evaluator is set up to save -only what it needs later. - -1110 -01:01:01,090 --> 01:01:04,670 -So, for example, at the point -where you've reduced - -1111 -01:01:04,670 --> 01:01:08,580 -evaluating an expression and an -environment to applying a - -1112 -01:01:08,580 --> 01:01:11,700 -procedure to some arguments, it -doesn't need that original - -1113 -01:01:11,700 --> 01:01:15,110 -environment anymore because any -environment stuff will be - -1114 -01:01:15,110 --> 01:01:18,160 -packaged inside the procedures -where the - -1115 -01:01:18,160 --> 01:01:20,160 -application's going to happen. - -1116 -01:01:20,160 --> 01:01:23,120 -All right, similarly, when -you're going along evaluating - -1117 -01:01:23,120 --> 01:01:25,910 -an argument list, when you've -finished evaluating the list, - -1118 -01:01:25,910 --> 01:01:28,200 -when you're finished evaluating -the last argument, - -1119 -01:01:28,200 --> 01:01:31,500 -you don't need that argument -list any more, right? - -1120 -01:01:31,500 --> 01:01:33,330 -And you don't need the -environment where those - -1121 -01:01:33,330 --> 01:01:36,690 -arguments would be -evaluated, OK? - -1122 -01:01:36,690 --> 01:01:40,890 -So the basic reason that this -interpreter is being so smart - -1123 -01:01:40,890 --> 01:01:43,050 -is that it's not being smart -at all, it's being stupid. - -1124 -01:01:43,050 --> 01:01:44,760 -It's just saying I'm -only going to save - -1125 -01:01:44,760 --> 01:01:46,010 -what I really need. - -1126 -01:01:46,010 --> 01:01:48,700 - - -1127 -01:01:48,700 --> 01:01:51,000 -Well, let me show you here. - -1128 -01:01:51,000 --> 01:01:54,880 - - -1129 -01:01:54,880 --> 01:01:58,310 -Here's the actual thing that's -making a tail recursive. - -1130 -01:01:58,310 --> 01:02:00,135 -Remember, it's the restore -of continue. - -1131 -01:02:00,135 --> 01:02:09,090 -It's saying when I go off to -evaluate the procedure body, I - -1132 -01:02:09,090 --> 01:02:12,090 -should tell eval to come back -to the place where that - -1133 -01:02:12,090 --> 01:02:15,170 -original evaluation was supposed -to come back to. - -1134 -01:02:15,170 --> 01:02:17,700 -So, in some sense, you want to -say what's the actual line - -1135 -01:02:17,700 --> 01:02:18,770 -that makes a tail recursive? - -1136 -01:02:18,770 --> 01:02:19,920 -It's that one. - -1137 -01:02:19,920 --> 01:02:23,680 -If I wanted to build a non-tail -recursive evaluator, - -1138 -01:02:23,680 --> 01:02:27,650 -for some strange reason, all I -would need to do is, instead - -1139 -01:02:27,650 --> 01:02:31,300 -of restoring continue at this -point, I'd set up a label down - -1140 -01:02:31,300 --> 01:02:35,340 -here called, "Where to come -back after you've finished - -1141 -01:02:35,340 --> 01:02:38,560 -applying the procedure." -Instead, I'd - -1142 -01:02:38,560 --> 01:02:39,920 -set continue to that. - -1143 -01:02:39,920 --> 01:02:42,240 -I'd go to eval-dispatch, -and then eval-dispatch - -1144 -01:02:42,240 --> 01:02:43,790 -would come back here. - -1145 -01:02:43,790 --> 01:02:45,920 -At that point, I would restore -continue and go to the - -1146 -01:02:45,920 --> 01:02:47,920 -original one. - -1147 -01:02:47,920 --> 01:02:51,790 -So here, the only consequence -of that would be to make it - -1148 -01:02:51,790 --> 01:02:52,840 -non-tail recursive. - -1149 -01:02:52,840 --> 01:02:55,340 -It would give you exactly the -same answers, except, if you - -1150 -01:02:55,340 --> 01:02:57,800 -did that iterative factorial -and all those iterative - -1151 -01:02:57,800 --> 01:02:59,500 -procedures, it would execute -recursively. - -1152 -01:02:59,500 --> 01:03:03,080 - - -1153 -01:03:03,080 --> 01:03:05,760 -Well, I lied to you a little -bit, but just a little bit, - -1154 -01:03:05,760 --> 01:03:07,670 -because I showed you a slightly -over-simplified - -1155 -01:03:07,670 --> 01:03:12,510 -evaluator where it assumes that -each procedure body has - -1156 -01:03:12,510 --> 01:03:13,890 -only one expression. - -1157 -01:03:13,890 --> 01:03:15,790 -Remember, in general, a -procedure has a sequence of - -1158 -01:03:15,790 --> 01:03:17,870 -expressions in it. - -1159 -01:03:17,870 --> 01:03:20,490 -So there's nothing really -conceptually new. - -1160 -01:03:20,490 --> 01:03:23,480 -Let me just show you the actual -evaluator that handles - -1161 -01:03:23,480 --> 01:03:24,730 -sequences of expressions. - -1162 -01:03:24,730 --> 01:03:28,470 - - -1163 -01:03:28,470 --> 01:03:30,650 -This is compound-apply now, and -the only difference from - -1164 -01:03:30,650 --> 01:03:35,980 -the old one is that, instead of -going off to eval directly, - -1165 -01:03:35,980 --> 01:03:38,510 -it takes the whole body of the -procedure, which, in this - -1166 -01:03:38,510 --> 01:03:40,920 -case, is a sequence of -expressions, and goes off to - -1167 -01:03:40,920 --> 01:03:42,670 -eval-sequence. - -1168 -01:03:42,670 --> 01:03:48,380 -And eval-sequence is a little -loop that, basically, does - -1169 -01:03:48,380 --> 01:03:49,980 -these evaluations -one at a time. - -1170 -01:03:49,980 --> 01:03:52,630 - - -1171 -01:03:52,630 --> 01:03:53,900 -So it does an evaluation. - -1172 -01:03:53,900 --> 01:03:56,110 -Says oh, when I come back, I'd -better come back here to do - -1173 -01:03:56,110 --> 01:03:58,440 -the next one. - -1174 -01:03:58,440 --> 01:04:00,410 -And, when I'm all done, when -I want to get the last - -1175 -01:04:00,410 --> 01:04:04,800 -expression, I just restore -my continue and go off to - -1176 -01:04:04,800 --> 01:04:06,410 -eval-dispatch. - -1177 -01:04:06,410 --> 01:04:08,880 -And, again, if you wanted for -some reason to break tail - -1178 -01:04:08,880 --> 01:04:11,690 -recursion in this evaluator, -all you need to do is not - -1179 -01:04:11,690 --> 01:04:14,900 -handle the last expression, -especially. - -1180 -01:04:14,900 --> 01:04:17,820 -Just say, after you've done the -last expression, come back - -1181 -01:04:17,820 --> 01:04:21,900 -to some other place after which -you restore continue. - -1182 -01:04:21,900 --> 01:04:24,920 -And, for some reason, a lot -of LISP evaluators tended - -1183 -01:04:24,920 --> 01:04:26,550 -to work that way. - -1184 -01:04:26,550 --> 01:04:29,300 -And the only consequence of -that is that iterative - -1185 -01:04:29,300 --> 01:04:31,614 -procedures built up stack. - -1186 -01:04:31,614 --> 01:04:35,670 -And it's not clear why -that happened. - -1187 -01:04:35,670 --> 01:04:36,210 -All right. - -1188 -01:04:36,210 --> 01:04:38,990 -Well, let me just sort of -summarize, since this is a lot - -1189 -01:04:38,990 --> 01:04:41,120 -of details in a big program. - -1190 -01:04:41,120 --> 01:04:44,040 -But the main point is that -it's no different, - -1191 -01:04:44,040 --> 01:04:47,060 -conceptually, from translating -any other program. - -1192 -01:04:47,060 --> 01:04:49,760 -And the main idea is that we -have this universal evaluator - -1193 -01:04:49,760 --> 01:04:51,870 -program, the meta-circular -evaluator. - -1194 -01:04:51,870 --> 01:04:53,250 -If we translate that -into LISP, then - -1195 -01:04:53,250 --> 01:04:54,560 -we have all of LISP. - -1196 -01:04:54,560 --> 01:04:57,980 -And that's all we did, OK? - -1197 -01:04:57,980 --> 01:04:59,680 -The second point is that -the magic's gone away. - -1198 -01:04:59,680 --> 01:05:01,970 -There should be no more magic -in this whole system, right? - -1199 -01:05:01,970 --> 01:05:04,820 - - -1200 -01:05:04,820 --> 01:05:08,720 -In principle, it should all be -very clear except, maybe, for - -1201 -01:05:08,720 --> 01:05:10,940 -how list structured -memory works, and - -1202 -01:05:10,940 --> 01:05:12,640 -we'll see that later. - -1203 -01:05:12,640 --> 01:05:15,450 -But that's not very hard. - -1204 -01:05:15,450 --> 01:05:18,720 -The third point is that all this -tail recursion came from - -1205 -01:05:18,720 --> 01:05:23,580 -the discipline of eval being -very careful to save only what - -1206 -01:05:23,580 --> 01:05:25,870 -it needs next time. - -1207 -01:05:25,870 --> 01:05:28,180 -It's not some arbitrary thing -where we're saying well, - -1208 -01:05:28,180 --> 01:05:30,440 -whenever we call a sub-routine, -we'll save all - -1209 -01:05:30,440 --> 01:05:33,940 -the registers in the world -and come back, right? - -1210 -01:05:33,940 --> 01:05:37,150 -See, sometimes it pays to really -worry about efficiency. - -1211 -01:05:37,150 --> 01:05:39,400 -And, when you're down in the -guts of your evaluator - -1212 -01:05:39,400 --> 01:05:42,560 -machine, it really pays to think -about things like that - -1213 -01:05:42,560 --> 01:05:45,230 -because it makes big -consequences. - -1214 -01:05:45,230 --> 01:05:49,680 -Well, I hope what this has -done is really made the - -1215 -01:05:49,680 --> 01:05:52,560 -evaluator seem concrete, -right? - -1216 -01:05:52,560 --> 01:05:57,120 -I hope you really believe that -somebody could hold a LISP - -1217 -01:05:57,120 --> 01:05:59,390 -evaluator in the palm -of their hand. - -1218 -01:05:59,390 --> 01:06:02,540 -Maybe to help you believe that, -here's a LISP evaluator - -1219 -01:06:02,540 --> 01:06:06,160 -that I'm holding the palm -of my hand, right? - -1220 -01:06:06,160 --> 01:06:11,750 -And this is a chip which is -actually quite a bit more - -1221 -01:06:11,750 --> 01:06:13,700 -complicated than the evaluator -I showed you. - -1222 -01:06:13,700 --> 01:06:17,815 - - -1223 -01:06:17,815 --> 01:06:19,200 -Maybe, here's a better -picture of it. - -1224 -01:06:19,200 --> 01:06:22,070 - - -1225 -01:06:22,070 --> 01:06:24,730 -What there is, is you can see -the same overall structure. - -1226 -01:06:24,730 --> 01:06:26,940 -This is a register array. - -1227 -01:06:26,940 --> 01:06:27,910 -These are the data paths. - -1228 -01:06:27,910 --> 01:06:29,800 -Here's a finite state -controller. - -1229 -01:06:29,800 --> 01:06:32,810 -And again, finite state, -that's all there is. - -1230 -01:06:32,810 --> 01:06:34,160 -And somewhere there's -external memory - -1231 -01:06:34,160 --> 01:06:35,750 -that'll worry about things. - -1232 -01:06:35,750 --> 01:06:38,090 -And this particular one is very -complicated because it's - -1233 -01:06:38,090 --> 01:06:41,450 -trying to run LISP fast. And -it has some very, very fast - -1234 -01:06:41,450 --> 01:06:45,570 -parallel operations in there -like, if you want to index - -1235 -01:06:45,570 --> 01:06:50,040 -into an array, simultaneously -check that the index is an - -1236 -01:06:50,040 --> 01:06:53,750 -integer, check that it doesn't -exceed the array bands, and go - -1237 -01:06:53,750 --> 01:06:55,810 -off and do the memory access, -and do all those things - -1238 -01:06:55,810 --> 01:06:57,120 -simultaneously. - -1239 -01:06:57,120 --> 01:06:58,970 -And then, later, if they're -all OK, actually - -1240 -01:06:58,970 --> 01:07:00,420 -get the value there. - -1241 -01:07:00,420 --> 01:07:02,520 -So there are a lot of -complicated operations in - -1242 -01:07:02,520 --> 01:07:06,550 -these data paths for making -LISP run in parallel. - -1243 -01:07:06,550 --> 01:07:10,640 -It's a completely non-risk -philosophy of evaluating LISP. - -1244 -01:07:10,640 --> 01:07:13,740 -And then, this microcode -is pretty complicated. - -1245 -01:07:13,740 --> 01:07:17,740 -Let's see, there's what? - -1246 -01:07:17,740 --> 01:07:23,600 -There's about 389 instructions -of 220-bit microcode sitting - -1247 -01:07:23,600 --> 01:07:27,940 -here because these are very -complicated data paths. - -1248 -01:07:27,940 --> 01:07:33,580 -And the whole thing has about -89,000 transistors, OK? - -1249 -01:07:33,580 --> 01:07:33,840 -OK. - -1250 -01:07:33,840 --> 01:07:37,970 -Well, I hope that that takes -away a lot of the mystery. - -1251 -01:07:37,970 --> 01:07:39,240 -Maybe somebody wants -to look at this. - -1252 -01:07:39,240 --> 01:07:42,048 - - -1253 -01:07:42,048 --> 01:07:43,298 -Yeah. - -1254 -01:07:43,298 --> 01:07:46,260 - - -1255 -01:07:46,260 --> 01:07:46,480 -OK. - -1256 -01:07:46,480 --> 01:07:47,730 -Let's stop. - -1257 -01:07:47,730 --> 01:07:55,890 - - -1258 -01:07:55,890 --> 01:07:57,815 -Questions? - -1259 -01:07:57,815 --> 01:08:00,130 -AUDIENCE: OK, now, it sounds -like what you're saying is - -1260 -01:08:00,130 --> 01:08:03,070 -that, with the restore continue -put in the proper - -1261 -01:08:03,070 --> 01:08:08,830 -place, that procedures that -would invoke a recursive - -1262 -01:08:08,830 --> 01:08:13,385 -process now invoke an integer -process just by the way that - -1263 -01:08:13,385 --> 01:08:15,165 -the eval signature is? - -1264 -01:08:15,165 --> 01:08:17,850 -PROFESSOR: I think the way I'd -prefer to put it is that, with - -1265 -01:08:17,850 --> 01:08:22,540 -restore continue put in the -wrong place, you can cause any - -1266 -01:08:22,540 --> 01:08:25,880 -syntactically-looking recursive -procedure, in fact, - -1267 -01:08:25,880 --> 01:08:28,029 -to build up stack as it runs. - -1268 -01:08:28,029 --> 01:08:34,350 -But there's no reason for that, -so you might want to - -1269 -01:08:34,350 --> 01:08:35,660 -play around with it. - -1270 -01:08:35,660 --> 01:08:38,640 -You can just switch around two -or three instructions in the - -1271 -01:08:38,640 --> 01:08:42,260 -way compound-apply comes back, -and you'll get something which - -1272 -01:08:42,260 --> 01:08:45,060 -isn't tail recursive. - -1273 -01:08:45,060 --> 01:08:47,670 -But the thing I wanted to -emphasize is there's no magic. - -1274 -01:08:47,670 --> 01:08:51,689 -It's not as if there's some -very clever pre-processing - -1275 -01:08:51,689 --> 01:08:55,540 -program that's looking at this -procedure, factorial iter, and - -1276 -01:08:55,540 --> 01:08:59,920 -say oh, gee, I really notice -that I don't have to push - -1277 -01:08:59,920 --> 01:09:01,060 -stack in order to do this. - -1278 -01:09:01,060 --> 01:09:03,760 -Some people think that that's -what's going on. - -1279 -01:09:03,760 --> 01:09:05,840 -It's something much, much more -dumb than that, it's this one - -1280 -01:09:05,840 --> 01:09:08,880 -place you're putting the -restore instruction. - -1281 -01:09:08,880 --> 01:09:10,353 -It's just automatic. - -1282 -01:09:10,353 --> 01:09:11,603 -AUDIENCE: OK. - -1283 -01:09:11,603 --> 01:09:14,217 - - -1284 -01:09:14,217 --> 01:09:16,109 -AUDIENCE: But that's not -affecting the time - -1285 -01:09:16,109 --> 01:09:17,850 -complexity is it? - -1286 -01:09:17,850 --> 01:09:18,275 -PROFESSOR: No. - -1287 -01:09:18,275 --> 01:09:21,810 -AUDIENCE: It's just that it's -handling it recursively - -1288 -01:09:21,810 --> 01:09:23,020 -instead of iteratively. - -1289 -01:09:23,020 --> 01:09:26,960 -But, in terms of the order of -time it takes to finish the - -1290 -01:09:26,960 --> 01:09:29,220 -operation, it's the same one -way or the other, right? - -1291 -01:09:29,220 --> 01:09:29,920 -PROFESSOR: Yes. - -1292 -01:09:29,920 --> 01:09:32,609 -Tail recursion is not going to -change the time complexity of - -1293 -01:09:32,609 --> 01:09:34,420 -anything because, in some sense, -it's the same algorithm - -1294 -01:09:34,420 --> 01:09:36,029 -that's going on. - -1295 -01:09:36,029 --> 01:09:38,790 -What it's doing is really making -this thing run as an - -1296 -01:09:38,790 --> 01:09:41,210 -iteration, right? - -1297 -01:09:41,210 --> 01:09:44,750 -Not going to run out of memory -counting up to a giant number - -1298 -01:09:44,750 --> 01:09:47,683 -simply because the stack -would get pushed. - -1299 -01:09:47,683 --> 01:09:49,970 -See, the thing you really -have to believe is - -1300 -01:09:49,970 --> 01:09:51,640 -that, when we write-- - -1301 -01:09:51,640 --> 01:09:53,040 -see, we've been writing all -these things called - -1302 -01:09:53,040 --> 01:09:57,990 -iterations, infinite loops, -define loop to be called loop. - -1303 -01:09:57,990 --> 01:10:01,660 - - -1304 -01:10:01,660 --> 01:10:05,390 -That's is as much an iteration -as if we wrote do forever - -1305 -01:10:05,390 --> 01:10:07,630 -loop, right? - -1306 -01:10:07,630 --> 01:10:09,280 -It's just syntactic sugar -as the difference. - -1307 -01:10:09,280 --> 01:10:14,730 -These things are real, honest -to god, iterations, right? - -1308 -01:10:14,730 --> 01:10:17,285 -They don't change the time -complexity, but they turn them - -1309 -01:10:17,285 --> 01:10:18,535 -into real iterations. - -1310 -01:10:18,535 --> 01:10:21,686 - - -1311 -01:10:21,686 --> 01:10:23,800 -All right, thank you. - -1312 -01:10:23,800 --> 01:10:42,633 - +1 +00:00:15,840 --> 00:00:20,260 +PROFESSOR: Well, I hope you appreciate that we have + +2 +00:00:20,260 --> 00:00:24,562 +inducted you into some real magic, + +3 +00:00:24,562 --> 00:00:29,500 +the magic of building languages, really building new languages. + +4 +00:00:29,500 --> 00:00:31,275 +What have we looked at? We've looked at + +5 +00:00:31,275 --> 00:00:38,925 +an Escher picture language: + +6 +00:00:38,925 --> 00:00:42,141 +this language invented by Peter Henderson. + +7 +00:00:42,141 --> 00:00:47,600 +We looked at digital logic language. + +8 +00:00:53,000 --> 00:00:56,944 +Let's see.We've looked at the query language. + +9 +00:00:59,700 --> 00:01:04,700 +And the thing you should realize is, even though these were toy examples, + +10 +00:01:04,700 --> 00:01:08,250 +they really are the kernels of really useful things. + +11 +00:01:08,250 --> 00:01:12,375 +So, for instance, the Escher picture language was taken by + +12 +00:01:12,375 --> 00:01:14,450 +Henry Wu, who's a student at MIT, + +13 +00:01:14,450 --> 00:01:20,350 +and developed into a real language for laying out PC boards, + +14 +00:01:20,350 --> 00:01:23,244 +based just on extending those structures. + +15 +00:01:23,244 --> 00:01:26,350 +And the digital logic language, Jerry mentioned when he showed it to you, + +16 +00:01:26,350 --> 00:01:30,850 +was really extended to be used as the basis for a simulator + +17 +00:01:30,850 --> 00:01:33,460 +that was used to design a real computer. + +18 +00:01:33,460 --> 00:01:37,510 +And the query language, of course, is kind of the germ of prologue. + +19 +00:01:37,510 --> 00:01:39,425 +So we built all of these languages, + +20 +00:01:39,425 --> 00:01:42,300 +they're all based on LISP. + +21 +00:01:43,630 --> 00:01:45,275 +A lot of people ask + +22 +00:01:45,275 --> 00:01:48,606 +what particular problems is LISP good for solving for? + +23 +00:01:48,606 --> 00:01:53,450 +The answer is LISP is not good for solving any particular problems. + +24 +00:01:53,450 --> 00:01:56,213 +What LISP is good for is constructing within it + +25 +00:01:56,213 --> 00:01:59,175 +the right language to solve the problems you want to solve, + +26 +00:01:59,175 --> 00:02:01,470 +and that's how you should think about it. + +27 +00:02:01,470 --> 00:02:04,326 +So all of these languages were based on LISP. + +28 +00:02:04,326 --> 00:02:06,925 +Now, what's LISP based on? + +29 +00:02:06,925 --> 00:02:09,400 +Where's that come from? Well, we looked at that too. + +30 +00:02:09,400 --> 00:02:22,935 +We looked at the meta-circular evaluator + +31 +00:02:22,935 --> 00:02:25,810 +and said well, LISP is based on LISP. + +32 +00:02:25,810 --> 00:02:28,275 +And when we start looking at that, + +33 +00:02:28,275 --> 00:02:29,950 +we've got to do some real magic, right? + +34 +00:02:29,950 --> 00:02:31,660 +So what does that mean, right? + +35 +00:02:31,660 --> 00:02:37,350 +Why operators, and fixed points, and the idea that + +36 +00:02:37,350 --> 00:02:41,000 +what this means is that LISP is somehow the fixed-point equation + +37 +00:02:41,000 --> 00:02:47,400 +for this funny set of things which are defined in terms of themselves. + +38 +00:02:47,400 --> 00:02:49,070 +Now, it's real magic. + +39 +00:02:49,070 --> 00:02:52,625 +Well, today, for a final piece of magic, + +40 +00:02:52,625 --> 00:03:01,852 +we're going to make all the magic go away. + +41 +00:03:06,430 --> 00:03:09,770 +We already know how to do that. + +42 +00:03:09,770 --> 00:03:13,135 +The idea is, we're going to take the register machine architecture + +43 +00:03:13,135 --> 00:03:15,500 +and show how to implement LISP on terms of that. + +44 +00:03:15,500 --> 00:03:21,325 +And, remember, the idea of the register machine is that + +45 +00:03:21,325 --> 00:03:24,800 +there's a fixed and finite part of the machine. + +46 +00:03:24,800 --> 00:03:27,050 +There's a finite-state controller, which does some + +47 +00:03:27,050 --> 00:03:30,510 +particular thing with a particular amount of hardware. + +48 +00:03:30,510 --> 00:03:33,550 +There are particular data paths, the operation the machine does + +49 +00:03:33,550 --> 00:03:37,725 +And then, in order to implement recursion and sustain the illusion of infinity, + +50 +00:03:37,725 --> 00:03:42,060 +there's some large amount of memory, which is the stack. + +51 +00:03:42,060 --> 00:03:47,025 +So, if we implement LISP in terms of a register machine, + +52 +00:03:47,025 --> 00:03:49,850 +then everything ought to become, at this point,completely concrete. + +53 +00:03:49,850 --> 00:03:51,650 +All the magic should go away. + +54 +00:03:51,650 --> 00:03:55,140 +And, by the end of this talk, I want you get the feeling + +55 +00:03:55,140 --> 00:03:59,675 +that, as opposed to this very mysterious meta-circular evaluator + +56 +00:03:59,675 --> 00:04:02,850 +that a LISP evaluator really is something that's concrete enough + +57 +00:04:02,850 --> 00:04:04,720 +that you can hold in the palm of your hand. + +58 +00:04:04,720 --> 00:04:06,450 +You should be able to imagine holding + +59 +00:04:06,450 --> 00:04:09,546 +holding a LISP interpreter there. + +60 +00:04:09,546 --> 00:04:10,950 +All right, how are we going to do this? + +61 +00:04:10,950 --> 00:04:13,960 +We already have all the ingredients. + +62 +00:04:13,960 --> 00:04:17,450 +See, what you learned last time from Jerry + +63 +00:04:17,450 --> 00:04:22,600 +is how to take any particular couple of LISP procedures + +64 +00:04:22,600 --> 00:04:28,210 +and hand-translate them into something that runs on a register machine. + +65 +00:04:28,210 --> 00:04:30,525 +So, to implement all of LISP on a register machine, + +66 +00:04:30,525 --> 00:04:33,600 +all we have to do is take the particular procedures + +67 +00:04:33,600 --> 00:04:36,050 +that are the meta-circular evaluator + +68 +00:04:36,050 --> 00:04:38,825 +and hand-translate them for a register machine. + +69 +00:04:38,825 --> 00:04:42,320 +And that does all of LISP, right? + +70 +00:04:42,320 --> 00:04:45,380 +So, in principle, we already know how to do this. + +71 +00:04:45,380 --> 00:04:51,275 +And, indeed, it's going to be no different, in kind, from + +72 +00:04:51,275 --> 00:04:54,670 +from translating, say, recursive factorial or recursive Fibonacci. + +73 +00:04:54,670 --> 00:04:56,840 +It's just bigger and there's more of it. + +74 +00:04:56,840 --> 00:05:01,375 +So it'd just be more details, but nothing really conceptually new. + +75 +00:05:01,375 --> 00:05:04,876 +And also, when we've done that, and the thing is completely explicit, + +76 +00:05:04,876 --> 00:05:06,990 +and we see how to implement LISP in terms of + +77 +00:05:06,990 --> 00:05:10,085 +the actual sequential register operations, + +78 +00:05:10,085 --> 00:05:14,810 +that's going to be our final most explicit model of LISP in this course. + +79 +00:05:14,810 --> 00:05:16,950 +And, remember, that's a progression through this course. + +80 +00:05:16,950 --> 00:05:20,100 +We started out with substitution, which is sort of like algebra. + +81 +00:05:20,100 --> 00:05:21,838 +And then we went to the environment model, + +82 +00:05:21,838 --> 00:05:26,125 +which talked about the actual frames and how they got linked together. + +83 +00:05:26,125 --> 00:05:31,080 +And then we made that more concrete in the meta-circular evaluator. + +84 +00:05:31,080 --> 00:05:34,360 +There are things the meta-circular evaluator doesn't tell us. + +85 +00:05:34,360 --> 00:05:36,090 +You should realize that. + +86 +00:05:36,090 --> 00:05:40,420 +For instance, it left unanswered the question of how + +87 +00:05:40,420 --> 00:05:45,175 +a procedure, like recursive factorial here, + +88 +00:05:45,175 --> 00:05:47,210 +somehow takes space that grows. + +89 +00:05:47,210 --> 00:05:51,948 +On the other hand, a procedure which also looks syntactically recursive, + +90 +00:05:51,948 --> 00:05:56,760 +called fact-iter, somehow doesn't take space.We justify , + +91 +00:05:56,760 --> 00:06:00,500 +We justify that it doesn't need to take space + +92 +00:06:00,500 --> 00:06:01,960 +by showing the substitution model. + +93 +00:06:01,960 --> 00:06:07,275 +But we didn't really say how it happens that the machine manages to do that, + +94 +00:06:07,275 --> 00:06:09,161 +that that has to do with the details + +95 +00:06:09,161 --> 00:06:12,250 +of how arguments are passed to procedures. + +96 +00:06:12,250 --> 00:06:15,846 +And that's the thing we didn't see in the meta-circular evaluator precisely + +97 +00:06:15,846 --> 00:06:19,700 +because the way arguments got passed to procedures in this LISP + +98 +00:06:19,700 --> 00:06:25,050 +depended on the way arguments got passed to procedures in this LISP. + +99 +00:06:26,070 --> 00:06:30,740 +But, now, that's going to become extremely explicit. + +100 +00:06:30,740 --> 00:06:31,230 +OK. + +101 +00:06:31,230 --> 00:06:34,426 +Well, before going on to the evaluator, + +102 +00:06:34,426 --> 00:06:37,600 +let me just give you a sense of what a whole LISP system looks like + +103 +00:06:37,600 --> 00:06:39,086 +so you can see the parts we're going to talk about + +104 +00:06:39,086 --> 00:06:43,250 +and the parts we're not going to talk about. + +105 +00:06:43,250 --> 00:06:48,675 +Let's see, over here is a happy LISP user, + +106 +00:06:48,675 --> 00:06:53,245 +and the LISP user is talking to something called the reader. + +107 +00:07:00,360 --> 00:07:14,170 +The reader's job in life is to take characters from the user + +108 +00:07:14,170 --> 00:07:17,960 +and turn them into data structures in something called + +109 +00:07:17,960 --> 00:07:21,405 +a list structure memory. + +110 +00:07:29,783 --> 00:07:32,653 +All right, so the reader is going to take + +111 +00:07:32,653 --> 00:07:36,953 +symbols, parentheses, and A's and B's, and 1s and 3s that you type in, + +112 +00:07:36,953 --> 00:07:39,150 +and turn these into actual list structure: + +113 +00:07:39,150 --> 00:07:39,156 +pairs, and pointers, and things. + +114 +00:07:39,156 --> 00:07:42,340 +pairs, and pointers, and things. + +115 +00:07:42,340 --> 00:07:45,850 +And so, by the time evaluator is going, there are no characters in the world. + +116 +00:07:45,850 --> 00:07:49,480 +And, of course, in more modern list systems, there's sort of + +117 +00:07:49,480 --> 00:07:52,325 +a big morass here that might sit between the user and the reader: + +118 +00:07:52,325 --> 00:07:54,775 +Windows systems, and top levels, + +119 +00:07:54,775 --> 00:07:56,280 +and mice, and all kinds of things. + +120 +00:07:56,280 --> 00:07:59,590 +But conceptually, characters are coming in. + +121 +00:07:59,590 --> 00:08:05,525 +All right, the reader transforms these into pointers + +122 +00:08:05,525 --> 00:08:08,275 +pointers to stuff in this memory, + +123 +00:08:08,275 --> 00:08:12,445 +and that's what the evaluator sees + +124 +00:08:15,300 --> 00:08:17,090 +OK? + +125 +00:08:17,090 --> 00:08:17,300 +The evaluator has a bunch of helpers. + +126 +00:08:17,300 --> 00:08:19,780 +The evaluator has a bunch of helpers. + +127 +00:08:19,780 --> 00:08:23,080 +It has all possible primitive operators you might want. + +128 +00:08:23,080 --> 00:08:28,400 +So there's a completely separate box, + +129 +00:08:28,400 --> 00:08:32,225 +a floating point unit, + +130 +00:08:32,225 --> 00:08:35,960 +or all sorts of things, which do the primitive operators. + +131 +00:08:35,960 --> 00:08:37,548 +And, if you want more special primitives, + +132 +00:08:37,548 --> 00:08:42,080 +you build more primitive operators, but they're separate from the evaluator. + +133 +00:08:42,080 --> 00:08:45,025 +The evaluator finally gets an answer + +134 +00:08:45,025 --> 00:08:50,450 +and communicates that to the printer. + +135 +00:08:50,780 --> 00:08:52,265 +And now, the printer's job in life is to take + +136 +00:08:52,265 --> 00:08:55,318 +this list structure coming from the evaluator, + +137 +00:08:55,318 --> 00:08:57,614 +and turn it back into characters, + +138 +00:09:01,700 --> 00:09:04,075 +and communicate them to the user through + +139 +00:09:04,075 --> 00:09:05,750 +whatever interface there is. + +140 +00:09:08,050 --> 00:09:12,670 +OK. Well, today, what we're going to talk about is this evaluator. + +141 +00:09:12,670 --> 00:09:15,200 +The primitive operators have nothing particular to do with LISP, + +142 +00:09:15,200 --> 00:09:19,175 +they're however you like to implement primitive operations. + +143 +00:09:19,175 --> 00:09:22,187 +The reader and printer are actually complicated, + +144 +00:09:22,187 --> 00:09:24,420 +but we're not going to talk about them. + +145 +00:09:24,420 --> 00:09:27,100 +They sort of have to do with details of how you might build + +146 +00:09:27,100 --> 00:09:29,900 +build up list structure from characters. + +147 +00:09:29,900 --> 00:09:32,490 +So that is a long story, but we're not going to talk about it, + +148 +00:09:32,490 --> 00:09:36,930 +the list structure memory, we'll talk about next time. + +149 +00:09:36,930 --> 00:09:40,125 +So, pretty much, except for the details of reading and printing, + +150 +00:09:40,125 --> 00:09:43,250 +the only mystery that's going to be left after you see the evaluator + +151 +00:09:43,250 --> 00:09:46,295 +is how you build list structure on conventional memories. + +152 +00:09:46,295 --> 00:09:50,580 +But we'll worry about that next time too. + +153 +00:09:50,580 --> 00:09:51,830 +OK. + +154 +00:09:53,350 --> 00:09:56,110 +Well, let's start talking about the evaluator. + +155 +00:09:56,110 --> 00:09:59,775 +The one that we're going to show you, of course, is not, + +156 +00:09:59,775 --> 00:10:01,120 +I think, nothing special about it. + +157 +00:10:01,120 --> 00:10:04,810 +It's just a particular register machine that runs LISP. + +158 +00:10:04,810 --> 00:10:09,890 +And it has seven registers, and here are the seven registers. + +159 +00:10:09,890 --> 00:10:14,925 +There's a register, called EXP, and its job is to + +160 +00:10:14,925 --> 00:10:18,370 +hold the expression to be evaluated. + +161 +00:10:18,370 --> 00:10:21,750 +And by that, I mean it's going to hold a pointer + +162 +00:10:21,750 --> 00:10:23,764 +to someplace in list structure memory that holds + +163 +00:10:23,764 --> 00:10:26,550 +the expression to be evaluated. + +164 +00:10:26,550 --> 00:10:31,000 +There's a register, called ENV, which holds the environment + +165 +00:10:31,000 --> 00:10:34,070 +in which this expression is to be evaluated. + +166 +00:10:34,070 --> 00:10:38,240 +And, again, I made a pointer. The environment is some data structure. + +167 +00:10:38,240 --> 00:10:40,425 +There's a register, called FUN, which will + +168 +00:10:40,425 --> 00:10:44,350 +which will hold the procedure to be applied when you go to apply a procedure. + +169 +00:10:44,350 --> 00:10:47,325 +A register, called ARGL, + +170 +00:10:47,325 --> 00:10:50,200 +which wants the list of evaluated arguments. + +171 +00:10:50,200 --> 00:10:53,140 +What you can start seeing here is the basic structure of the evaluator. + +172 +00:10:53,140 --> 00:10:54,490 +Remember how evaluators work. + +173 +00:10:54,490 --> 00:10:57,670 +There's a piece that takes expressions and environments, + +174 +00:10:57,670 --> 00:10:59,100 +and there's a piece that takes + +175 +00:10:59,100 --> 00:11:03,480 +functions, or procedures and arguments. + +176 +00:11:03,480 --> 00:11:07,294 +And going back and forth around here is the eval/apply loop. + +177 +00:11:07,294 --> 00:11:10,000 +So those are the basic pieces of the eval and apply. + +178 +00:11:10,000 --> 00:11:11,610 +Then there's some other things, there's continue. + +179 +00:11:11,610 --> 00:11:15,340 +You just saw before how the continue register is used to + +180 +00:11:15,340 --> 00:11:18,750 +implement recursion and stack discipline. + +181 +00:11:18,750 --> 00:11:23,925 +There's a register that's going to hold the result of some evaluation. + +182 +00:11:23,925 --> 00:11:26,555 +And then, besides that, there's one temporary register, + +183 +00:11:26,555 --> 00:11:29,280 +called UNEV, which typically, in the evaluator, + +184 +00:11:29,280 --> 00:11:30,625 +is going to be used to hold + +185 +00:11:30,625 --> 00:11:33,950 +temporary pieces of the expression you're working on, + +186 +00:11:33,950 --> 00:11:37,150 +which you haven't gotten around to evaluate yet, right? + +187 +00:11:37,150 --> 00:11:40,646 +So there's my machine: a seven-register machine. + +188 +00:11:40,646 --> 00:11:42,981 +And, of course, you might want to make a machine with + +189 +00:11:42,981 --> 00:11:44,846 +a lot more registers to get better performance, + +190 +00:11:44,846 --> 00:11:48,480 +but this is just a tiny, minimal one. + +191 +00:11:48,480 --> 00:11:49,780 +Well, how about the data paths? + +192 +00:11:49,780 --> 00:11:55,100 +This machine has a lot of special operations for LISP. + +193 +00:11:55,100 --> 00:12:00,120 +So, here are some typical data paths. + +194 +00:12:00,120 --> 00:12:03,320 +A typical one might be, oh, assign to the VAL register + +195 +00:12:03,320 --> 00:12:06,710 +the contents of the EXP register. + +196 +00:12:06,710 --> 00:12:11,900 +In terms of those diagrams you saw, that's a little button on some arrow. + +197 +00:12:11,900 --> 00:12:13,699 +Here's a more complicated one. + +198 +00:12:13,699 --> 00:12:18,810 +It says branch, if the thing in the expression register is + +199 +00:12:18,810 --> 00:12:23,550 +a conditional to some label here, called the ev-conditional. + +200 +00:12:23,550 --> 00:12:26,230 +And you can imagine this implemented in a lot of different ways. + +201 +00:12:26,230 --> 00:12:30,600 +You might imagine this conditional test as a special purpose sub-routine, + +202 +00:12:30,600 --> 00:12:33,845 +and conditional might be represented as some data abstraction + +203 +00:12:33,845 --> 00:12:36,610 +that you don't care about at this level of detail. + +204 +00:12:36,610 --> 00:12:37,980 +So that might be done as a sub-routine. + +205 +00:12:37,980 --> 00:12:40,900 +This might be a machine with hardware-types, + +206 +00:12:40,900 --> 00:12:45,350 +and conditional might be testing some bits for a particular code. + +207 +00:12:45,350 --> 00:12:46,417 +There are all sorts of ways that's + +208 +00:12:46,417 --> 00:12:50,190 +beneath the level of abstraction we're looking at. + +209 +00:12:50,190 --> 00:12:53,247 +Another kind of operation, and there are a lot of different operations + +210 +00:12:53,247 --> 00:12:56,840 +assigned to EXP, the first clause of what's in EXP. + +211 +00:12:56,840 --> 00:12:59,260 +This might be part of processing a conditional. + +212 +00:12:59,260 --> 00:13:04,258 +And, again, first clause is some selector whose details we don't care about. + +213 +00:13:04,258 --> 00:13:06,300 +And you can, again, imagine that as a sub-routine + +214 +00:13:06,300 --> 00:13:09,180 +which'll do some list operations, or you can imagine that as + +215 +00:13:09,180 --> 00:13:12,170 +something that's built directly into hardware. + +216 +00:13:12,170 --> 00:13:15,222 +The reason I keep saying you can imagine it built directly into hardware + +217 +00:13:15,222 --> 00:13:18,360 +is even though there are a lot of operations, + +218 +00:13:18,360 --> 00:13:19,740 +there are still a fixed number of them. + +219 +00:13:19,740 --> 00:13:22,370 +I forget how many, maybe 150. + +220 +00:13:22,370 --> 00:13:26,167 +So, it's plausible to think of building these directly into hardware. + +221 +00:13:26,167 --> 00:13:28,275 +Here's a more complicated one. + +222 +00:13:28,275 --> 00:13:31,500 +You can see this has to do with looking up the values of variables. + +223 +00:13:31,500 --> 00:13:35,550 +It says assign to the VAL register the result of looking up + +224 +00:13:35,550 --> 00:13:39,025 +the variable value of some particular expression, + +225 +00:13:39,025 --> 00:13:42,600 +which,in this case, is supposed to be a variable in some environment. + +226 +00:13:42,600 --> 00:13:46,280 +And this'll be some operation that searches through + +227 +00:13:46,280 --> 00:13:49,325 +the environment structure, however it is represented, + +228 +00:13:49,325 --> 00:13:52,019 +and goes and looks up that variable. + +229 +00:13:52,019 --> 00:13:55,790 +And, again, that's below the level of detail that we're thinking about. + +230 +00:13:55,790 --> 00:13:57,300 +This has to do with the details of + +231 +00:13:57,300 --> 00:14:00,075 +the data structures for representing environments. + +232 +00:14:00,075 --> 00:14:03,679 +But, anyway, there is this fixed and finite number + +233 +00:14:03,679 --> 00:14:06,325 +of operations in the register machine. + +234 +00:14:08,500 --> 00:14:11,720 +Well, what's its overall structure? + +235 +00:14:11,720 --> 00:14:14,675 +Those are some typical operations. + +236 +00:14:14,675 --> 00:14:16,442 +Remember what we have to do, + +237 +00:14:16,442 --> 00:14:20,172 +we have to take the meta-circular evaluator-- + +238 +00:14:20,172 --> 00:14:22,767 +and here's a piece of the meta-circular evaluator. + +239 +00:14:22,767 --> 00:14:28,050 +This is the one using abstract syntax that's in the book. + +240 +00:14:28,050 --> 00:14:33,500 +It's a little bit different from the one that Jerry shows you. + +241 +00:14:33,500 --> 00:14:37,874 +And the main thing to remember about the evaluator is that + +242 +00:14:37,874 --> 00:14:43,425 +it's doing some sort of case analysis on the kinds of expressions: + +243 +00:14:43,425 --> 00:14:48,560 +so if it's either self-evaluated, or quoted, or whatever else. + +244 +00:14:48,560 --> 00:14:50,864 +And then, in the general case where + +245 +00:14:50,864 --> 00:14:53,550 +the expression it's looking at is an application, + +246 +00:14:53,550 --> 00:14:55,750 +there's some tricky recursions going on. + +247 +00:14:55,750 --> 00:15:00,730 +First of all, eval has to call itself both to evaluate the + +248 +00:15:00,730 --> 00:15:05,880 +operator and to evaluate all the operands. + +249 +00:15:05,880 --> 00:15:10,850 +So there's this sort of red recursion of values walking down the tree + +250 +00:15:10,850 --> 00:15:12,270 +that's really the easy recursion. + +251 +00:15:12,270 --> 00:15:14,750 +That's just a val walking down this tree of expressions. + +252 +00:15:14,750 --> 00:15:16,305 +Then, in the evaluator, there's a hard recursion. + +253 +00:15:16,305 --> 00:15:21,650 +There's the red to green. Eval calls apply. + +254 +00:15:22,470 --> 00:15:26,450 +That's the case where evaluating a procedure or argument + +255 +00:15:26,450 --> 00:15:30,370 +reduces to applying the procedure to the list of arguments. + +256 +00:15:30,370 --> 00:15:33,875 +And then, apply comes over here. + +257 +00:15:34,770 --> 00:15:37,650 +Apply takes a procedure and arguments + +258 +00:15:37,650 --> 00:15:41,051 +and, in the general case where there's a compound procedure, + +259 +00:15:41,051 --> 00:15:44,560 +apply goes around and green calls red. Eval -- + +260 +00:15:44,560 --> 00:15:48,170 +Apply comes around and calls eval again. + +261 +00:15:48,170 --> 00:15:51,330 +Eval's the body of the procedure in the result of + +262 +00:15:51,330 --> 00:15:55,485 +extending the environment with the parameters of the procedure + +263 +00:15:55,485 --> 00:15:57,379 +by binding the arguments. + +264 +00:15:59,620 --> 00:16:01,626 +Except in the primitive case, where it just calls something else + +265 +00:16:01,626 --> 00:16:05,980 +primitive-apply, which is not really the business of the evaluator. + +266 +00:16:05,980 --> 00:16:11,249 +So this sort of red to green, to red to green, that's the + +267 +00:16:11,249 --> 00:16:13,975 +that's the eval/apply loop, + +268 +00:16:13,975 --> 00:16:19,475 +and that's the thing that we're going to want to see in the evaluator. + +269 +00:16:19,475 --> 00:16:21,079 +Well, it won't surprise you at all that + +270 +00:16:21,079 --> 00:16:27,470 +the two big pieces of this evaluator correspond to eval and apply. + +271 +00:16:27,470 --> 00:16:29,548 +There's a piece called eval-dispatch, + +272 +00:16:29,548 --> 00:16:31,913 +and a piece called apply-dispatch. + +273 +00:16:31,913 --> 00:16:34,095 +And, before we get into the details of the code, + +274 +00:16:34,095 --> 00:16:37,760 +the way to understand this is to think, again, in terms of + +275 +00:16:37,760 --> 00:16:41,870 +these pieces of the evaluator having contracts with the rest of the world. + +276 +00:16:41,870 --> 00:16:45,780 +What do they do from the outside before getting into the grungy details? + +277 +00:16:45,780 --> 00:16:51,300 +Well, the contract for eval-dispatch-- remember, it corresponds to eval. + +278 +00:16:51,300 --> 00:16:54,100 +It's got to evaluate an expression in an environment. + +279 +00:16:54,100 --> 00:16:56,525 +So, in particular, what this one is going to do, + +280 +00:16:56,525 --> 00:16:59,920 +eval-dispatch will assume that, when you call it, that + +281 +00:16:59,920 --> 00:17:03,640 +the expression you want to evaluate is in the EXP register. + +282 +00:17:03,640 --> 00:17:07,750 +The environment in which you want the evaluation to take place + +283 +00:17:07,750 --> 00:17:09,569 +is in the ENV register. + +284 +00:17:09,569 --> 00:17:11,899 +And continue tells you the place where the machine should + +285 +00:17:11,899 --> 00:17:14,575 +go next when the evaluation is done. + +286 +00:17:17,440 --> 00:17:21,070 +Eval-dispatch's contract is that it'll actually perform that evaluation, + +287 +00:17:21,070 --> 00:17:26,619 +and, at the end of which, it'll end up at the place specified by continue. + +288 +00:17:26,619 --> 00:17:29,825 +The result of the evaluation will be in the VAL register. + +289 +00:17:29,825 --> 00:17:32,964 +And it just warns you, it makes no promises about + +290 +00:17:32,964 --> 00:17:35,230 +what happens to the registers. + +291 +00:17:35,230 --> 00:17:37,490 +All other registers might be destroyed. + +292 +00:17:37,490 --> 00:17:41,412 +So, there's one piece, OK? + +293 +00:17:41,412 --> 00:17:45,925 +Together, the pieces, apply-dispatch that corresponds to apply, + +294 +00:17:45,925 --> 00:17:48,731 +it's got to apply a procedure to some arguments, + +295 +00:17:48,731 --> 00:17:51,434 +so it assumes that this register, ARGL, + +296 +00:17:51,434 --> 00:17:54,540 +contains a list of the evaluated arguments. + +297 +00:17:54,540 --> 00:17:57,220 +FUN contains the procedure. + +298 +00:17:57,220 --> 00:17:59,500 +Those correspond to the arguments to the apply + +299 +00:17:59,500 --> 00:18:02,300 +procedure in the meta-circular evaluator. + +300 +00:18:03,970 --> 00:18:07,676 +And apply, in this particular evaluator, we're going to use a discipline which says + +301 +00:18:07,676 --> 00:18:12,556 +the place the machine should go to next when apply is done + +302 +00:18:12,556 --> 00:18:17,070 +is, at the moment apply-dispatch is called at the top of the stack + +303 +00:18:17,070 --> 00:18:21,840 +that's just discipline for the way this particular machine's organized. + +304 +00:18:21,840 --> 00:18:23,700 +And now apply's contract is given all that. + +305 +00:18:23,700 --> 00:18:25,540 +It'll perform the application. + +306 +00:18:25,540 --> 00:18:28,890 +The result of that application will end up in VAL. + +307 +00:18:28,890 --> 00:18:31,120 +The stack will be popped. + +308 +00:18:31,120 --> 00:18:34,841 +And, again, the contents of all the other registers may be destroyed. + +309 +00:18:34,841 --> 00:18:39,760 +All right? So that's the basic organization of this machine. + +310 +00:18:39,760 --> 00:18:41,110 +Let's break for a little bit and see if there are any + +311 +00:18:41,110 --> 00:18:42,700 +questions, and then we'll do a real example. + +312 +00:19:47,850 --> 00:19:50,175 +Well, let's take the register machine now, + +313 +00:19:50,175 --> 00:19:52,175 +and actually step through, + +314 +00:19:52,200 --> 00:19:58,708 +and really, in real detail, so you see completely concrete + +315 +00:19:58,708 --> 00:20:03,400 +how some expressions are evaluated, all right? + +316 +00:20:03,400 --> 00:20:09,300 +So, let's start with a very simple expression. + +317 +00:20:09,620 --> 00:20:14,150 +Let's evaluate the expression 1. + +318 +00:20:18,775 --> 00:20:21,279 +And we need an environment, so let's imagine that + +319 +00:20:21,279 --> 00:20:24,025 +somewhere there's an environment, we'll call it E,0. + +320 +00:20:30,260 --> 00:20:35,620 +And just, since we'll use these later, + +321 +00:20:35,620 --> 00:20:38,360 +we obviously don't really need anything to evaluate 1. + +322 +00:20:38,360 --> 00:20:41,202 +But, just for reference later, let's assume that E,0 has in it + +323 +00:20:41,202 --> 00:20:49,140 +an X that's bound to 3 and a Y that's bound to 4, OK? + +324 +00:20:49,140 --> 00:20:53,700 +And now what we're going to do is we're going to evaluate 1 + +325 +00:20:53,700 --> 00:20:59,650 +in this environment, and so the ENV register has a pointer + +326 +00:20:59,650 --> 00:21:03,560 +to this environment, E,0, all right? + +327 +00:21:03,560 --> 00:21:05,650 +So let's watch that thing go. + +328 +00:21:05,650 --> 00:21:08,260 +What I'm going to do is step through the code. + +329 +00:21:08,260 --> 00:21:09,782 +And, let's see, I'll be the controller. + +330 +00:21:09,782 --> 00:21:12,980 +And now what I need, since this gets rather complicated, + +331 +00:21:12,980 --> 00:21:16,830 +is a very little execution unit. + +332 +00:21:16,830 --> 00:21:21,310 +So here's the execution unit, OK? + +333 +00:21:22,624 --> 00:21:23,874 +OK. + +334 +00:21:27,088 --> 00:21:28,590 +OK. + +335 +00:21:28,590 --> 00:21:30,533 +All right, now we're going to start. + +336 +00:21:30,533 --> 00:21:33,700 +We're going to start the machine at eval-dispatch, right? + +337 +00:21:33,700 --> 00:21:35,875 +That's the beginning of this. + +338 +00:21:35,875 --> 00:21:39,320 +Eval-dispatch is going to look at the expression in dispatch, + +339 +00:21:39,320 --> 00:21:40,875 +just like eval + +340 +00:21:40,875 --> 00:21:41,760 +where we look at the very first thing. + +341 +00:21:41,760 --> 00:21:47,950 +We branch on whether or not this expression is self-evaluating. + +342 +00:21:47,950 --> 00:21:52,171 +Self-evaluating is some abstraction we put into the machine-- + +343 +00:21:52,171 --> 00:21:53,515 +it's going to be true for numbers-- + +344 +00:21:53,515 --> 00:21:56,775 +to a place called ev-self-eval, right? + +345 +00:21:56,775 --> 00:22:00,010 +So me, being the controller, looks at ev-self-eval, + +346 +00:22:00,010 --> 00:22:02,607 +so we'll go over to there. + +347 +00:22:02,607 --> 00:22:08,128 +Ev-self-eval says fine, assign to val + +348 +00:22:08,128 --> 00:22:15,220 +whatever is in the expression unit, OK? + +349 +00:22:15,220 --> 00:22:17,600 +And I have a bug + +350 +00:22:17,600 --> 00:22:17,650 +because what I didn't do when I initialized this machine + +351 +00:22:17,650 --> 00:22:21,625 +because what I didn't do when I initialized this machine + +352 +00:22:21,625 --> 00:22:24,650 +is also say what's supposed to happen when it's done, + +353 +00:22:24,650 --> 00:22:27,640 +so I should have started out the machine with + +354 +00:22:27,640 --> 00:22:32,050 +done being in the continue register, OK? + +355 +00:22:32,050 --> 00:22:33,079 +So we assign to VAL. + +356 +00:22:33,079 --> 00:22:38,000 +And now go to fetch of continue, and now change-- + +357 +00:22:38,000 --> 00:22:40,000 +OK. + +358 +00:22:40,000 --> 00:22:42,160 +OK, let's try something harder. + +359 +00:22:42,160 --> 00:22:44,787 +Let's reset the machine here, + +360 +00:22:44,787 --> 00:22:51,562 +and we'll put in the expression register, X, OK? + +361 +00:22:56,710 --> 00:22:59,610 +Start again at eval-dispatch. + +362 +00:22:59,610 --> 00:23:01,690 +Check, is it self-evaluating? + +363 +00:23:01,690 --> 00:23:02,650 +No. + +364 +00:23:02,650 --> 00:23:04,630 +Is it a variable? + +365 +00:23:04,630 --> 00:23:05,560 +Yes. + +366 +00:23:05,560 --> 00:23:08,380 +We go off to ev-variable. + +367 +00:23:08,380 --> 00:23:12,131 +It says assign to VAL, + +368 +00:23:12,131 --> 00:23:16,150 +look up the variable value in the expression register, OK? + +369 +00:23:21,075 --> 00:23:23,625 +Go to fetch of continue. + +370 +00:23:23,625 --> 00:23:24,875 +PROFESSOR: Done. + +371 +00:23:27,252 --> 00:23:28,950 +PROFESSOR: OK. + +372 +00:23:28,950 --> 00:23:29,430 +All right. + +373 +00:23:29,430 --> 00:23:31,330 +Well, that's the basic idea. + +374 +00:23:31,330 --> 00:23:32,688 +That's a simple operation of the machine. + +375 +00:23:32,688 --> 00:23:36,070 +Now, let's actually do something a little bit more interesting. + +376 +00:23:36,070 --> 00:23:49,678 +Let's look at the expression the sum of x and y. + +377 +00:23:49,678 --> 00:23:50,130 +OK. + +378 +00:23:50,130 --> 00:23:54,350 +And now we'll see how you start unrolling these expression trees. + +379 +00:23:56,625 --> 00:23:59,434 +Well, start again at eval-dispatch. + +380 +00:24:04,610 --> 00:24:05,935 +Self-evaluating? + +381 +00:24:05,935 --> 00:24:06,850 +No. + +382 +00:24:06,850 --> 00:24:07,850 +Variable? No. + +383 +00:24:07,850 --> 00:24:10,270 +All the other special forms which I didn't write down, + +384 +00:24:10,270 --> 00:24:12,480 +like quote, and lambda, and set, and whatever, + +385 +00:24:12,480 --> 00:24:13,260 +it's none of those. + +386 +00:24:13,260 --> 00:24:15,889 +It turns out to be an application, + +387 +00:24:15,889 --> 00:24:19,970 +so we go off to ev-application, OK? + +388 +00:24:19,970 --> 00:24:25,580 +Ev-application, remember what it's going to do overall. + +389 +00:24:25,580 --> 00:24:28,310 +It is going to evaluate the operator. + +390 +00:24:28,310 --> 00:24:32,225 +It's going to evaluate the arguments, + +391 +00:24:32,225 --> 00:24:35,060 +and then it's going to go apply them. + +392 +00:24:35,060 --> 00:24:37,887 +So, before we start, since we're being very literal, + +393 +00:24:37,887 --> 00:24:40,435 +we'd better remember that, somewhere in this environment, + +394 +00:24:40,435 --> 00:24:44,475 +it's linked to another environment in which + +395 +00:24:44,475 --> 00:24:51,475 +plus is bound to the primitive procedure plus + +396 +00:24:51,475 --> 00:24:55,340 +before we get an unknown variable in our machine. + +397 +00:24:55,340 --> 00:24:58,625 +OK, so we're at ev-application. + +398 +00:24:59,700 --> 00:25:04,405 +OK, assign to UNEV the operands + +399 +00:25:04,405 --> 00:25:07,920 +of what's in the expression register, OK? + +400 +00:25:07,920 --> 00:25:09,230 +Those are the operands. + +401 +00:25:09,230 --> 00:25:13,225 +UNEV's a temporary register where we're going to save them. + +402 +00:25:13,225 --> 00:25:13,860 +PROFESSOR: I'm assigning. + +403 +00:25:13,860 --> 00:25:18,070 +PROFESSOR: Assign to x the operator. + +404 +00:25:18,070 --> 00:25:21,849 +Now, notice we've destroyed that expression in x, + +405 +00:25:21,849 --> 00:25:25,820 +but the piece that we need is now in UNEV. OK. + +406 +00:25:25,820 --> 00:25:28,750 +Now, we're going to get set up to recursively evaluate the operator. + +407 +00:25:28,750 --> 00:25:32,825 +Save the continue register on the stack. + +408 +00:25:34,870 --> 00:25:37,600 +Save the environment. + +409 +00:25:40,520 --> 00:25:43,594 +Save UNEV. + +410 +00:25:49,409 --> 00:25:56,234 +OK, assign to continue a label called eval-args. + +411 +00:26:01,400 --> 00:26:01,950 +Now, what have we done? + +412 +00:26:01,950 --> 00:26:04,380 +We've set up for a recursive call. + +413 +00:26:04,380 --> 00:26:06,280 +We're about to go to eval-dispatch. + +414 +00:26:06,280 --> 00:26:10,230 +We've set up for a recursive call to eval-dispatch. + +415 +00:26:10,230 --> 00:26:11,020 +What did we do? + +416 +00:26:11,020 --> 00:26:14,425 +We took the things we're going to need later, + +417 +00:26:14,425 --> 00:26:16,363 +those operands that were in UNEV; + +418 +00:26:16,363 --> 00:26:19,073 +the environment in which we're going to eventually have to, + +419 +00:26:19,073 --> 00:26:22,129 +maybe, evaluate those operands; + +420 +00:26:22,129 --> 00:26:25,265 +the place we eventually want to go to, which, in this case, was done; + +421 +00:26:25,265 --> 00:26:27,275 +we've saved them on the stack. + +422 +00:26:27,275 --> 00:26:28,724 +The reason we saved them on the stack is because + +423 +00:26:28,724 --> 00:26:33,550 +eval-dispatch makes no promises about what registers it may destroy. + +424 +00:26:33,550 --> 00:26:35,020 +So all that stuff is saved on the stack. + +425 +00:26:35,020 --> 00:26:37,380 +Now, we've set up eval-dispatch's contract. + +426 +00:26:37,380 --> 00:26:40,964 +There's a new expression, which is the operator plus; + +427 +00:26:40,964 --> 00:26:44,250 +a new environment, although, in this case, it's the same one; + +428 +00:26:44,250 --> 00:26:47,600 +and a new place to go to when you're done, which is eval-args. + +429 +00:26:47,600 --> 00:26:48,130 +So that's set up. + +430 +00:26:48,130 --> 00:26:50,890 +Now, we're going to go off to eval-dispatch. + +431 +00:26:50,890 --> 00:26:53,090 +Here we are back at eval-dispatch. + +432 +00:26:53,090 --> 00:26:54,490 +It's not self-evaluating. + +433 +00:26:54,490 --> 00:27:00,147 +Oh, it's a variable, so we'd better go off to ev-variable, right? + +434 +00:27:00,147 --> 00:27:02,880 +Ev-variable is assigned to VAL. + +435 +00:27:02,880 --> 00:27:08,770 +Look up the variable value of the expression, OK? + +436 +00:27:08,770 --> 00:27:13,000 +So VAL is the primitive procedure plus, OK? + +437 +00:27:13,000 --> 00:27:15,020 +And go to fetch of continue. + +438 +00:27:15,020 --> 00:27:16,050 +PROFESSOR: Eval-args. + +439 +00:27:16,050 --> 00:27:19,340 +PROFESSOR: Right, which is now eval-args not done. + +440 +00:27:19,340 --> 00:27:23,071 +So we come back here at eval-args, and what do we do? + +441 +00:27:23,071 --> 00:27:29,050 +We're going to restore the stuff that we saved, so we restore UNEV. + +442 +00:27:29,050 --> 00:27:32,900 +And notice, there, it wasn't necessary, although, in general, it would be. + +443 +00:27:32,900 --> 00:27:35,430 +It might be some arbitrary evaluation that happened. + +444 +00:27:35,430 --> 00:27:54,900 +We restore ENV. OK, we assign to FUN fetch of VAL. + +445 +00:27:58,620 --> 00:28:04,340 +OK, now, we're going to go off and start evaluating some arguments. + +446 +00:28:04,340 --> 00:28:08,330 +Well, first thing we'd better do is save FUN because some + +447 +00:28:08,330 --> 00:28:13,675 +arbitrary stuff might happen in that evaluation. + +448 +00:28:15,330 --> 00:28:20,750 +We initialize the argument list. Assign to argl an empty argument list, + +449 +00:28:20,750 --> 00:28:25,460 +and go to eval-arg-loop, OK? + +450 +00:28:25,460 --> 00:28:29,580 +At eval-arg-loop, the idea of this is we're going to + +451 +00:28:29,580 --> 00:28:33,540 +evaluate the pieces of the expressions that are in UNEV, one by one, + +452 +00:28:33,540 --> 00:28:35,688 +and move them from unevaluated in UNEV + +453 +00:28:35,688 --> 00:28:38,090 +to evaluated in the arg list, OK? + +454 +00:28:38,090 --> 00:28:42,400 +So we save argl. + +455 +00:28:43,950 --> 00:28:49,145 +We assign to x the first operand of the stuff in UNEV. + +456 +00:28:53,772 --> 00:28:55,890 +Now, we check and see if that was the last operand. + +457 +00:28:55,890 --> 00:28:59,190 +In this case, it is not, all right? + +458 +00:28:59,190 --> 00:29:02,975 +So we save the environment. + +459 +00:29:07,850 --> 00:29:13,500 +We save UNEV because those are all things we might need later. + +460 +00:29:13,500 --> 00:29:15,800 +We're going to need the environment to do some more evaluations. + +461 +00:29:15,800 --> 00:29:20,340 +We're going to need UNEV to look at what the rest of those arguments were. + +462 +00:29:20,340 --> 00:29:26,053 +We're going to assign continue a place called accumulate-args, or accumulate-arg. + +463 +00:29:30,898 --> 00:29:36,810 +OK, now, we've set up for another call to eval-dispatch, OK? + +464 +00:29:36,810 --> 00:29:39,125 +All right, now, let me short-circuit this + +465 +00:29:39,125 --> 00:29:41,090 +so we don't go through the details of eval-dispatch. + +466 +00:29:41,090 --> 00:29:45,103 +Eval-dispatch's contract says I'm going to end up, + +467 +00:29:45,103 --> 00:29:48,240 +the world will end up, with the value of evaluating this expression + +468 +00:29:48,240 --> 00:29:50,270 +in this environment in the VAL register, + +469 +00:29:50,270 --> 00:29:51,320 +and I'll end up there. + +470 +00:29:51,320 --> 00:29:58,010 +So we short-circuit all of this, and a 3 ends up in VAL. + +471 +00:29:58,010 --> 00:29:59,768 +And, when we return from eval-dispatch, + +472 +00:29:59,768 --> 00:30:02,110 +we're going to return to accumulate-arg. + +473 +00:30:02,110 --> 00:30:03,555 +PROFESSOR: Accumulate-arg. + +474 +00:30:06,185 --> 00:30:08,720 +PROFESSOR: With 3 in the VAL register, OK? + +475 +00:30:08,720 --> 00:30:10,650 +So that short-circuited that evaluation. + +476 +00:30:10,650 --> 00:30:11,320 +Now, what do we do? + +477 +00:30:11,320 --> 00:30:13,689 +We're going to go back and look at the rest of the arguments, + +478 +00:30:13,689 --> 00:30:15,609 +so we restore UNEV. + +479 +00:30:17,513 --> 00:30:28,650 +We restore ENV. We restore argl. + +480 +00:30:28,650 --> 00:30:29,170 +One thing. + +481 +00:30:29,170 --> 00:30:30,536 +PROFESSOR: Oops! + +482 +00:30:30,536 --> 00:30:31,290 +Parity error. + +483 +00:30:31,290 --> 00:30:33,465 +[LAUGHTER] + +484 +00:30:33,465 --> 00:30:34,905 +PROFESSOR: Restore argl. + +485 +00:30:41,650 --> 00:30:42,900 +PROFESSOR: OK. + +486 +00:30:45,570 --> 00:30:50,400 +OK, we assign to argl consing on + +487 +00:30:50,400 --> 00:30:53,130 +fetch of the value register to what's in argl. + +488 +00:30:58,985 --> 00:31:05,025 +OK, we assign to UNEV the rest of the operands in fetch of UNEV, + +489 +00:31:08,700 --> 00:31:11,516 +and we go back to eval-arg-loop. + +490 +00:31:11,516 --> 00:31:12,280 +PROFESSOR: Eval-arg-loop. + +491 +00:31:12,280 --> 00:31:13,530 +PROFESSOR: OK. + +492 +00:31:15,880 --> 00:31:17,375 +Now, we're about to do the next argument, + +493 +00:31:17,375 --> 00:31:19,800 +so the first thing we do is save argl. + +494 +00:31:25,400 --> 00:31:31,803 +OK, we assign to x the first operand of fetch of UNEV. + +495 +00:31:34,650 --> 00:31:38,925 +OK,we test and see if that's the last operand.In this case, it is + +496 +00:31:38,925 --> 00:31:43,173 +so we're going to go to a special place that says evaluate the last argument + +497 +00:31:43,173 --> 00:31:44,965 +because, notice,after evaluating the argument, + +498 +00:31:44,965 --> 00:31:47,446 +we don't need the environment any more. + +499 +00:31:47,446 --> 00:31:50,250 +That's going to be the difference. + +500 +00:31:50,250 --> 00:31:52,054 +So here, at eval-last-arg, + +501 +00:31:52,054 --> 00:31:55,382 +which is assigned to continue accumulate-last-arg, + +502 +00:32:04,275 --> 00:32:06,900 +now, we're set up again for eval-dispatch. + +503 +00:32:06,900 --> 00:32:08,620 +We've got a place to go to when we're done. + +504 +00:32:08,620 --> 00:32:09,840 +We've got an expression. + +505 +00:32:09,840 --> 00:32:11,330 +We've got an environment. + +506 +00:32:11,330 --> 00:32:14,370 +OK, so we'll short-circuit the call to eval-dispatch. + +507 +00:32:14,370 --> 00:32:16,700 +And what'll happen is there's a y there, + +508 +00:32:16,700 --> 00:32:21,060 +it's 4 in that environment, so VAL will end up with 4 in it. + +509 +00:32:21,060 --> 00:32:25,450 +And, then, we're going to end up at accumulate-last-arg, OK? + +510 +00:32:25,450 --> 00:32:30,525 +So, at accumulate-last-arg, we restore argl. + +511 +00:32:41,490 --> 00:32:45,835 +We assign to argl cons of fetch of the new value onto it, + +512 +00:32:45,835 --> 00:32:49,850 +so we cons a 4 onto that. + +513 +00:32:49,850 --> 00:32:53,446 +We restore what was saved in the function register. + +514 +00:32:53,446 --> 00:32:56,277 +And notice, in this case, it had not been destroyed, + +515 +00:32:56,277 --> 00:32:59,132 +but in general, it will be. + +516 +00:32:59,132 --> 00:33:02,850 +And now, we're ready to go off to apply-dispatch, all right? + +517 +00:33:02,850 --> 00:33:04,510 +So we've just gone through the eval. + +518 +00:33:04,510 --> 00:33:07,980 +We evaluated the argument, the operator, and the arguments, + +519 +00:33:07,980 --> 00:33:09,580 +and now, we're about to apply them. + +520 +00:33:09,580 --> 00:33:17,481 +So we come off to apply-dispatch here, OK? + +521 +00:33:17,481 --> 00:33:20,575 +We come off to apply-dispatch, + +522 +00:33:20,575 --> 00:33:23,450 +and we're going to check whether it's a primitive or a compound procedure. + +523 +00:33:23,450 --> 00:33:24,116 +PROFESSOR: Yes. + +524 +00:33:24,116 --> 00:33:24,830 +PROFESSOR: All right. + +525 +00:33:24,830 --> 00:33:27,375 +So, in this case, it's a primitive procedure, + +526 +00:33:27,375 --> 00:33:29,790 +and we go off to primitive-apply. + +527 +00:33:29,790 --> 00:33:34,130 +So we go off to primitive-apply, and it says + +528 +00:33:34,130 --> 00:33:38,360 +assign to VAL the result of applying primitive procedure + +529 +00:33:38,360 --> 00:33:40,940 +of the function to the argument list. + +530 +00:33:40,940 --> 00:33:42,540 +PROFESSOR: I don't know how to add. + +531 +00:33:42,540 --> 00:33:43,995 +I'm just an execution unit. + +532 +00:33:43,995 --> 00:33:45,350 +PROFESSOR: Well, I don't know how to add either. + +533 +00:33:45,350 --> 00:33:48,360 +I'm just the evaluator, so we need a primitive operator. + +534 +00:33:48,360 --> 00:33:50,925 +Let's see, so the primitive operator, what's the + +535 +00:33:50,925 --> 00:33:52,605 +What's the sum of 3 and 4? + +536 +00:33:52,605 --> 00:33:53,205 +AUDIENCE: 7. + +537 +00:33:53,205 --> 00:33:55,050 +PROFESSOR: OK, 7. + +538 +00:33:55,050 --> 00:33:55,999 +PROFESSOR: Thank you. + +539 +00:33:58,837 --> 00:34:00,850 +PROFESSOR: Now, we restore continue, + +540 +00:34:11,275 --> 00:34:12,900 +and we go to fetch of continue. + +541 +00:34:12,900 --> 00:34:13,880 +PROFESSOR: Done. + +542 +00:34:13,880 --> 00:34:14,929 +PROFESSOR: OK. + +543 +00:34:14,929 --> 00:34:18,413 +Well, that was in as much detail as you will ever see. + +544 +00:34:18,413 --> 00:34:21,590 +We'll never do it in as much detail again. + +545 +00:34:21,590 --> 00:34:25,233 +One very important thing to notice is that + +546 +00:34:25,233 --> 00:34:29,780 +we just executed a recursive procedure, right? + +547 +00:34:29,780 --> 00:34:31,172 +This whole thing, we used a stack + +548 +00:34:31,172 --> 00:34:33,070 +and the evaluator was recursive. + +549 +00:34:33,070 --> 00:34:36,480 +A lot of people think the reason that you need a stack + +550 +00:34:36,480 --> 00:34:39,090 +and recursion in an evaluator is because you might be + +551 +00:34:39,090 --> 00:34:42,150 +evaluating recursive procedures like factorial or Fibonacci. + +552 +00:34:42,150 --> 00:34:43,670 +It's not true. + +553 +00:34:43,670 --> 00:34:46,110 +So you notice we did recursion here, and all we evaluated was + +554 +00:34:46,110 --> 00:34:48,010 +plus X, Y, all right? + +555 +00:34:48,010 --> 00:34:51,219 +The reason that you need recursion in the evaluator is + +556 +00:34:51,219 --> 00:34:54,450 +because the evaluation process, itself, is recursive, all right? + +557 +00:34:54,450 --> 00:34:57,760 +It's not because the procedure that you might be evaluating in LISP + +558 +00:34:57,760 --> 00:34:59,270 +is a recursive procedure. + +559 +00:34:59,270 --> 00:35:00,411 +So that's an important thing + +560 +00:35:00,411 --> 00:35:03,010 +that people get confused about a lot. + +561 +00:35:03,010 --> 00:35:06,280 +The other thing to notice is that, when we're done here, + +562 +00:35:06,280 --> 00:35:07,120 +we're really done. + +563 +00:35:07,120 --> 00:35:10,878 +Not only are we at done, but + +564 +00:35:10,878 --> 00:35:13,810 +there's no accumulated stuff on the stack, right? + +565 +00:35:13,810 --> 00:35:17,170 +The machine is back to its initial state, all right? + +566 +00:35:17,170 --> 00:35:19,715 +So that's part of what it means to be done. + +567 +00:35:19,715 --> 00:35:26,410 +Another way to say that is the evaluation process has reduced + +568 +00:35:26,410 --> 00:35:33,245 +the expression, plus X, Y, to the value here, 7. + +569 +00:35:33,245 --> 00:35:36,010 +And by reduced, I mean a very particular thing. + +570 +00:35:36,010 --> 00:35:38,180 +It means that there's nothing left on the stack. + +571 +00:35:38,180 --> 00:35:40,743 +The machine is now in the same state, + +572 +00:35:40,743 --> 00:35:42,723 +except there's something in the value register. + +573 +00:35:42,723 --> 00:35:44,520 +It's not part of a sub-problem of anything. + +574 +00:35:44,520 --> 00:35:46,210 +There's nothing to go back to. + +575 +00:35:46,210 --> 00:35:46,440 +OK. + +576 +00:35:46,440 --> 00:35:47,690 +Let's break. + +577 +00:35:49,712 --> 00:35:50,159 +Question? + +578 +00:35:50,159 --> 00:35:54,027 +AUDIENCE: The question here, in the stack, + +579 +00:35:54,027 --> 00:35:55,820 +is because the data may be recursive. + +580 +00:35:55,820 --> 00:35:59,312 +You may have embedded expressions, for instance. + +581 +00:35:59,312 --> 00:36:02,080 +PROFESSOR: Yes, because you might have embedded expressions. + +582 +00:36:02,080 --> 00:36:04,774 +But, again, don't confuse that + +583 +00:36:04,774 --> 00:36:07,718 +with what people sometimes mean by the data may be recursive, + +584 +00:36:07,718 --> 00:36:12,930 +which is to say you have these list-structured, recursive data list operations. + +585 +00:36:12,930 --> 00:36:13,804 +That has nothing to do with it. + +586 +00:36:13,804 --> 00:36:17,363 +It's simply that the expressions contain sub-expressions. + +587 +00:36:17,363 --> 00:36:19,618 +Yeah? + +588 +00:36:19,618 --> 00:36:23,457 +AUDIENCE: Why is it that the order of the arguments in the arg list got reversed? + +589 +00:36:23,457 --> 00:36:27,260 +PROFESSOR: Ah! Yes, I should've mentioned that. + +590 +00:36:27,260 --> 00:36:29,075 +Here, the reason the order is reversed-- + +591 +00:36:32,507 --> 00:36:36,050 +it's a question of what you mean by reversed. + +592 +00:36:36,050 --> 00:36:40,624 +I believe it was Newton. + +593 +00:36:40,624 --> 00:36:43,800 +In the very early part of optics, people realized that, + +594 +00:36:43,800 --> 00:36:45,500 +when you look through the lens of your eye, + +595 +00:36:45,500 --> 00:36:46,730 +the image was up-side down. + +596 +00:36:46,730 --> 00:36:48,044 +And there was a lot of argument about + +597 +00:36:48,044 --> 00:36:51,280 +why that didn't mean you saw things up-side down. + +598 +00:36:51,280 --> 00:36:52,860 +So it's sort of the same issue. + +599 +00:36:52,860 --> 00:36:54,810 +Reversed from what? + +600 +00:36:54,810 --> 00:36:57,940 +So we just need some convention. + +601 +00:36:57,940 --> 00:37:01,730 +The reason that they're coming at 4, 3 is because we're + +602 +00:37:01,730 --> 00:37:04,520 +taking UNEV and consing the result onto argl. + +603 +00:37:04,520 --> 00:37:06,771 +So you have to realize you've made that convention. + +604 +00:37:06,771 --> 00:37:09,987 +The place that you have to realize that-- + +605 +00:37:09,987 --> 00:37:11,230 +well, there's actually two places. + +606 +00:37:11,230 --> 00:37:12,910 +One is in apply-primitive-operator, + +607 +00:37:12,910 --> 00:37:16,610 +which has to realize that the arguments to primitives go in, + +608 +00:37:16,610 --> 00:37:19,490 +in the opposite order from the way you're writing them down. + +609 +00:37:19,490 --> 00:37:21,008 +And the other one is, we'll see later + +610 +00:37:21,008 --> 00:37:24,016 +when you actually go to bind a function's parameters, + +611 +00:37:24,016 --> 00:37:25,745 +you should realize the arguments are going to come in + +612 +00:37:25,745 --> 00:37:28,870 +from the opposite order of the variables to which you're binding them. + +613 +00:37:28,870 --> 00:37:31,830 +So, if you just keep track of that, there's no problem. + +614 +00:37:31,830 --> 00:37:33,900 +Also, this is completely arbitrary + +615 +00:37:33,900 --> 00:37:37,420 +because, if we'd done, say, an iteration through a vector assigning them, + +616 +00:37:37,420 --> 00:37:40,730 +they might come out in the other order, OK? + +617 +00:37:40,730 --> 00:37:45,085 +So it's just a convention of the way this particular evaluator works. + +618 +00:37:45,085 --> 00:37:46,335 +All right, let's take a break. + +619 +00:38:41,840 --> 00:38:45,609 +We just saw evaluating an expression and, + +620 +00:38:45,609 --> 00:38:46,950 +of course, that was very simple one. + +621 +00:38:46,950 --> 00:38:50,247 +But, in essence, it would be no different + +622 +00:38:50,247 --> 00:38:52,039 +if it was some big nested expression, + +623 +00:38:52,039 --> 00:38:55,130 +so there would just be deeper recursion on the stack. + +624 +00:38:55,130 --> 00:38:56,470 +But what I want to do now is show you the last piece. + +625 +00:38:56,470 --> 00:39:01,013 +I want to walk you around this eval and apply loop, right? + +626 +00:39:01,013 --> 00:39:03,000 +That's the thing we haven't seen, really. + +627 +00:39:03,000 --> 00:39:05,200 +We haven't seen any compound procedures + +628 +00:39:05,200 --> 00:39:07,925 +where evalutation of procedure reduces to + +629 +00:39:07,925 --> 00:39:12,250 +where applying of procedure reduces to evaluating the body of the procedure, + +630 +00:39:12,250 --> 00:39:15,810 +so let's just suppose we had this. + +631 +00:39:15,810 --> 00:39:18,075 +Suppose we were looking at the procedure + +632 +00:39:18,075 --> 00:39:33,995 +define F of A and B to be the sum of A and B. + +633 +00:39:33,995 --> 00:39:37,325 +So, as we typed in that procedure previously, + +634 +00:39:37,325 --> 00:39:42,275 +and now we're going to evaluate F of X and Y + +635 +00:39:42,275 --> 00:39:44,209 +again, in this environment, E,0, + +636 +00:39:44,209 --> 00:39:47,280 +where X is bound to 3 and Y is bound to 4. + +637 +00:39:50,650 --> 00:39:53,825 +When the defined is executed, remember, there's a lambda here, + +638 +00:39:53,825 --> 00:39:55,950 +and lambdas create procedures. + +639 +00:39:55,950 --> 00:40:00,815 +And, basically, what will happen is, in E,0, + +640 +00:40:00,815 --> 00:40:03,563 +we'll end up with a binding for F, + +641 +00:40:03,563 --> 00:40:07,151 +which will say F is a procedure, + +642 +00:40:07,151 --> 00:40:16,495 +and its args are A and B, and its body is plus a,b. + +643 +00:40:17,843 --> 00:40:21,053 +So that's what the environment would have looked like + +644 +00:40:21,053 --> 00:40:22,675 +had we made that definition. + +645 +00:40:24,225 --> 00:40:28,600 +Then, when we go to evaluate F of X and Y, + +646 +00:40:28,600 --> 00:40:31,615 +we'll go through exactly the same process that we did before. + +647 +00:40:31,615 --> 00:40:33,096 +It's even the same expression. + +648 +00:40:33,096 --> 00:40:36,030 +The only difference is that F, instead of having primitive + +649 +00:40:36,030 --> 00:40:39,250 +"plus" in it, will have this thing. + +650 +00:40:41,040 --> 00:40:43,600 +And so we'll go through exactly the same process, + +651 +00:40:43,600 --> 00:40:47,864 +except this time, when we end up at apply-dispatch, + +652 +00:40:47,864 --> 00:40:50,285 +the function register, instead of having primitive plus, + +653 +00:40:50,285 --> 00:40:54,300 +will have a thing that will represent it saying procedure, + +654 +00:40:54,300 --> 00:41:06,275 +where the args are A and B, and the body is plus A, B. + +655 +00:41:07,875 --> 00:41:11,092 +And, again, what I mean, by its ENV, I mean there's a pointer to it, + +656 +00:41:11,092 --> 00:41:13,280 +so don't worry that I'm writing a lot of stuff there. + +657 +00:41:13,280 --> 00:41:15,636 +There's a pointer to this procedure data structure. + +658 +00:41:17,170 --> 00:41:20,960 +OK, so, we're in exactly the same situation. + +659 +00:41:20,960 --> 00:41:26,480 +We get to apply-dispatch, so, here, we come to apply-dispatch. + +660 +00:41:26,480 --> 00:41:30,010 +Last time, we branched off to a primitive procedure. + +661 +00:41:30,010 --> 00:41:34,550 +Here, it says oh, we now have a compound procedure, + +662 +00:41:34,550 --> 00:41:36,911 +so we're going to go off to compound-apply. + +663 +00:41:38,475 --> 00:41:40,075 +Now, what's compound-apply? + +664 +00:41:41,925 --> 00:41:45,090 +Well, remember what the meta-circular evaluator did? + +665 +00:41:45,090 --> 00:41:49,903 +Compound-apply said we're going to evaluate + +666 +00:41:49,903 --> 00:41:54,120 +the body of the procedure in some new environment. + +667 +00:41:54,120 --> 00:41:56,730 +Where does that new environment come from? + +668 +00:41:56,730 --> 00:42:01,362 +We take the environment that was packaged with the procedure, + +669 +00:42:03,029 --> 00:42:05,791 +we bind the parameters of the procedure + +670 +00:42:05,791 --> 00:42:09,759 +to the arguments that we're passing in, + +671 +00:42:09,759 --> 00:42:14,990 +and use that as a new frame to extend the procedure environment. + +672 +00:42:14,990 --> 00:42:21,630 +And that's the environment in which we evaluate the procedure body, right? + +673 +00:42:21,630 --> 00:42:24,470 +That's going around the apply/eval loop. + +674 +00:42:24,470 --> 00:42:27,988 +That's apply coming back to call eval, all right? + +675 +00:42:30,910 --> 00:42:32,860 +OK. + +676 +00:42:32,860 --> 00:42:36,787 +So, now, that's all we have to do in compound-apply. + +677 +00:42:36,787 --> 00:42:37,720 +What are we going to do? + +678 +00:42:37,720 --> 00:42:40,975 +We're going to manufacture a new environment. + +679 +00:42:43,550 --> 00:42:46,768 +And we're going to manufacture a new environment that, + +680 +00:42:46,768 --> 00:42:48,310 +let's see, that we'll call E,1. + +681 +00:42:52,900 --> 00:42:57,310 +E,1 is going to be some environment where the + +682 +00:42:57,310 --> 00:43:01,765 +where the parameters of the procedure, where A is bound to 3 + +683 +00:43:01,765 --> 00:43:05,768 +and B is bound to 4, and it's linked to E,0 + +684 +00:43:05,768 --> 00:43:09,270 +because that's where f is defined. + +685 +00:43:09,270 --> 00:43:12,050 +And, in this environment, we're going to evaluate the body of the procedure. + +686 +00:43:12,050 --> 00:43:13,870 +So let's look at that, all right? + +687 +00:43:16,525 --> 00:43:20,690 +All right, here we are at compound-apply, which says + +688 +00:43:20,690 --> 00:43:24,500 +assign to the expression register + +689 +00:43:24,500 --> 00:43:28,163 +the body of the procedure that's in the function register. + +690 +00:43:28,163 --> 00:43:42,450 +So I assign to the expression register the procedure body, OK? + +691 +00:43:42,450 --> 00:43:45,825 +That's going to be evaluated in an environment + +692 +00:43:45,825 --> 00:43:51,300 +which is formed by making some bindings + +693 +00:43:51,300 --> 00:43:53,673 +using information determined by the procedure-- + +694 +00:43:53,673 --> 00:43:55,320 +that's what's in FUN-- + +695 +00:43:55,320 --> 00:43:57,800 +and the argument list. + +696 +00:43:57,800 --> 00:44:00,230 +And let's not worry about exactly what that does, + +697 +00:44:00,230 --> 00:44:01,930 +but you can see the information's there. + +698 +00:44:01,930 --> 00:44:05,948 +So make bindings will say oh, the procedure, itself, + +699 +00:44:05,948 --> 00:44:07,950 +had an environment attached to it. + +700 +00:44:07,950 --> 00:44:09,320 +I didn't write that quite here. + +701 +00:44:09,320 --> 00:44:11,300 +I should've said in environment + +702 +00:44:11,300 --> 00:44:13,660 +because every procedure gets built with an environment. + +703 +00:44:13,660 --> 00:44:16,600 +So, from that environment, it knows + +704 +00:44:16,600 --> 00:44:19,290 +what the procedure's definition environment is. + +705 +00:44:19,290 --> 00:44:21,830 +It knows what the arguments are. + +706 +00:44:21,830 --> 00:44:24,280 +It looks at argl, and then you see a reversal convention here. + +707 +00:44:24,280 --> 00:44:27,062 +It just has to know that argl is reversed, + +708 +00:44:27,062 --> 00:44:29,990 +and it builds this frame, E,1. + +709 +00:44:29,990 --> 00:44:33,364 +All right, so, let's assume that that's what make bindings returns, + +710 +00:44:33,364 --> 00:44:36,225 +so it assigns to ENV this thing, E,1. + +711 +00:44:41,490 --> 00:44:46,890 +All right, the next thing it says is restore continue. + +712 +00:44:46,890 --> 00:44:48,760 +Remember what continue was here? + +713 +00:44:48,760 --> 00:44:52,240 +It got put up in the last segment. + +714 +00:44:52,240 --> 00:44:54,020 +Continue got stored. + +715 +00:44:54,020 --> 00:44:56,565 +That was the original done, which said what are you going to do + +716 +00:44:56,565 --> 00:44:59,920 +after you're done with this particular application? + +717 +00:44:59,920 --> 00:45:01,560 +It was one of the very first things that happened + +718 +00:45:01,560 --> 00:45:03,920 +when we evaluated the application. + +719 +00:45:03,920 --> 00:45:06,860 +And now, finally, we're going to restore continue. + +720 +00:45:06,860 --> 00:45:09,290 +Remember apply-dispatch's contract. + +721 +00:45:09,290 --> 00:45:12,035 +It assumes that where it should go to next was on the stack, + +722 +00:45:12,035 --> 00:45:13,590 +and there it was on the stack. + +723 +00:45:13,590 --> 00:45:19,940 +Continue has done, and now we're going to go back to eval-dispatch. + +724 +00:45:19,940 --> 00:45:20,970 +We're set up again. + +725 +00:45:20,970 --> 00:45:25,511 +We have an expression, an environment, and a place to go to. + +726 +00:45:25,511 --> 00:45:29,940 +We're not going to go through that because it's sort of the same expression. + +727 +00:45:35,167 --> 00:45:39,342 +OK, but the thing, again, to notice is, at this point, + +728 +00:45:39,342 --> 00:45:44,830 +we have reduced the original expression, F,X,Y, right? + +729 +00:45:44,830 --> 00:45:48,755 +We've reduced evaluating F,X,Y in environment E,0 + +730 +00:45:48,755 --> 00:45:52,670 +to evaluate plus A, B in E,1. + +731 +00:45:52,670 --> 00:45:55,720 +And notice, nothing's on the stack, right? + +732 +00:45:55,720 --> 00:45:56,830 +It's a reduction. + +733 +00:45:56,830 --> 00:46:01,769 +At this point, the machine does not contain, as part of its state, + +734 +00:46:01,769 --> 00:46:05,493 +the fact that it's in the middle of evaluating some procedure called f, + +735 +00:46:05,493 --> 00:46:07,669 +that's gone, right? + +736 +00:46:07,669 --> 00:46:13,072 +There's no accumulated state, OK? + +737 +00:46:13,072 --> 00:46:14,370 +Again, that's a very important idea. + +738 +00:46:14,370 --> 00:46:18,396 +That's the meaning of, when we used to write in the substitution model, + +739 +00:46:18,396 --> 00:46:21,350 +this expression reduces to that expression. + +740 +00:46:21,350 --> 00:46:22,660 +And you don't have to remember anything. + +741 +00:46:22,660 --> 00:46:24,500 +And here, you see the meaning of reduction. + +742 +00:46:24,500 --> 00:46:26,160 +At this point, there is nothing on the stack. + +743 +00:46:31,590 --> 00:46:35,240 +See, that has very important consequences. + +744 +00:46:35,240 --> 00:46:38,325 +Let's go back and look at iterative factorial, + +745 +00:46:40,425 --> 00:46:45,130 +all right? Remember, this was some sort of loop and doing iter. + +746 +00:46:45,130 --> 00:46:49,430 +And we kept saying that's an iterative procedure, right? + +747 +00:46:49,430 --> 00:47:04,660 +And what we wrote, remember, are things like, we said, + +748 +00:47:04,660 --> 00:47:12,360 +fact-iter of 5. + +749 +00:47:12,360 --> 00:47:19,030 +We wrote things like reduces to iter of 1, and 1, and 5, + +750 +00:47:19,030 --> 00:47:25,324 +which reduces to iter of 1, and 2, and 5, + +751 +00:47:25,324 --> 00:47:27,079 +and so on, and so on, and so on. + +752 +00:47:27,079 --> 00:47:28,175 +And we kept saying well, look, + +753 +00:47:28,175 --> 00:47:31,720 +you don't have to build up any storage to do that. + +754 +00:47:31,720 --> 00:47:35,040 +And we waved our hands, and said in principle, there's no storage needed. + +755 +00:47:35,040 --> 00:47:36,170 +Now, you see no storage needed. + +756 +00:47:36,170 --> 00:47:39,090 +Each of these is a real reduction, right? + +757 +00:47:39,090 --> 00:47:42,825 +As you walk through these expressions, + +758 +00:47:47,300 --> 00:47:51,370 +As you walk through these expressions, what you'll see + +759 +00:47:51,370 --> 00:47:53,751 +are these expressions on the stack + +760 +00:47:53,751 --> 00:47:56,425 +in some particular environment, + +761 +00:47:56,425 --> 00:48:00,023 +and then these expressions in the EXP register + +762 +00:48:00,023 --> 00:48:01,575 +in some particular environment. + +763 +00:48:01,575 --> 00:48:04,365 +And, at each point, there'll be no accumulated stuff on the stack + +764 +00:48:04,365 --> 00:48:06,100 +because each one's a real reduction, OK? + +765 +00:48:09,135 --> 00:48:10,581 +All right, so, for example, + +766 +00:48:10,581 --> 00:48:13,460 +just to go through it in a little bit more care, + +767 +00:48:13,460 --> 00:48:17,108 +if I start out with an expression that says something like, + +768 +00:48:17,825 --> 00:48:34,400 +oh, say, fact-iter of 5 in some environment + +769 +00:48:41,900 --> 00:48:46,810 +that will, at some point, create an environment + +770 +00:48:46,810 --> 00:48:48,549 +in which n is down to 5. + +771 +00:48:51,340 --> 00:48:52,590 +Let's call that-- + +772 +00:48:55,750 --> 00:49:02,757 +And, at some point, the machine will reduce this whole thing + +773 +00:49:02,757 --> 00:49:07,673 +to a thing that says that's really iter + +774 +00:49:07,673 --> 00:49:15,875 +of 1, and 1, and n, evaluated in this environment, E,1 + +775 +00:49:15,875 --> 00:49:17,160 +with nothing on the stack. + +776 +00:49:17,160 --> 00:49:20,710 +See, at this moment, the machine is not remembering + +777 +00:49:20,710 --> 00:49:22,500 +that evaluating this expression, iter-- + +778 +00:49:25,000 --> 00:49:29,366 +which is the loop-- is part of this thing called iterative factorial. + +779 +00:49:29,366 --> 00:49:30,590 +It's not remembering that. + +780 +00:49:30,590 --> 00:49:33,170 +It's just reducing the expression to that, right? + +781 +00:49:33,170 --> 00:49:38,050 +If we look again at the body of iterative factorial, + +782 +00:49:38,050 --> 00:49:42,810 +this expression has reduced to that expression. + +783 +00:49:42,810 --> 00:49:44,060 +Oh, I shouldn't have the n there. + +784 +00:49:46,590 --> 00:49:53,340 +It's a slightly different convention from the slide to the program, OK? + +785 +00:49:53,340 --> 00:49:56,124 +And, then, what's the body of iter? + +786 +00:49:56,124 --> 00:49:58,625 +Well, iter's going to be an if, + +787 +00:49:58,625 --> 00:50:00,060 +and I won't go through the details of if. + +788 +00:50:00,060 --> 00:50:02,225 +It'll evaluate the predicate. + +789 +00:50:02,225 --> 00:50:03,810 +In this case, it'll be false. + +790 +00:50:03,810 --> 00:50:09,850 +And this iter will now reduce to the expression + +791 +00:50:09,850 --> 00:50:21,620 +iter of whatever it says, star, counter product, and-- + +792 +00:50:21,620 --> 00:50:22,650 +what does it say-- + +793 +00:50:22,650 --> 00:50:32,975 +plus counter 1 in some other environment, by this time, E,2, + +794 +00:50:32,975 --> 00:50:43,200 +where E,2 will be set up having bindings for product and counter, right? + +795 +00:50:43,200 --> 00:50:45,140 +And it'll reduce to that, right? + +796 +00:50:45,140 --> 00:50:47,156 +It won't be remembering that it's part of + +797 +00:50:47,156 --> 00:50:49,340 +something that it has to return to. + +798 +00:50:49,340 --> 00:50:53,053 +And when iter calls iter again, it'll reduce to another thing that looks like this + +799 +00:50:53,053 --> 00:50:59,160 +in some environment, E,3, which has new bindings for product and counter. + +800 +00:50:59,160 --> 00:51:08,450 +So, if you're wondering, see, if you've always been queasy + +801 +00:51:08,450 --> 00:51:10,678 +about how it is we've been saying those procedures + +802 +00:51:10,678 --> 00:51:12,458 +that look syntactically recursive, + +803 +00:51:12,458 --> 00:51:18,100 +are, in fact, iterative, run in constant space, + +804 +00:51:18,100 --> 00:51:19,750 +well, I don't know if this makes you less queasy, + +805 +00:51:19,750 --> 00:51:21,230 +but at least it shows you what's happening. + +806 +00:51:21,230 --> 00:51:22,830 +There really isn't any buildup there. + +807 +00:51:25,910 --> 00:51:27,984 +Now, you might ask well, is there buildup + +808 +00:51:27,984 --> 00:51:31,710 +in principle in these environment frames? + +809 +00:51:31,710 --> 00:51:32,375 +And the answer is yeah, + +810 +00:51:32,375 --> 00:51:32,443 +you have to make these new environment frames, + +811 +00:51:32,443 --> 00:51:33,848 +you have to make these new environment frames, + +812 +00:51:33,848 --> 00:51:36,440 +but you don't have to hang onto them when you're done. + +813 +00:51:36,440 --> 00:51:40,720 +They can be garbage collected, or the space can be reused automatically. + +814 +00:51:40,720 --> 00:51:43,250 +But you see the control structure of the evaluator + +815 +00:51:43,250 --> 00:51:47,020 +is really using this idea that you actually have a reduction, + +816 +00:51:47,020 --> 00:51:50,132 +so these procedures really are iterative procedures. + +817 +00:51:50,132 --> 00:51:51,382 +All right, let's stop for questions. + +818 +00:52:02,288 --> 00:52:03,538 +All right, let's break. + +819 +00:52:48,770 --> 00:52:52,775 +Let me contrast the iterative procedure + +820 +00:52:52,775 --> 00:52:56,000 +just so you'll see where space does build up with a recursive procedure, + +821 +00:52:56,000 --> 00:52:58,030 +so you can see the difference. + +822 +00:52:58,030 --> 00:53:02,880 +Let's look at the evaluation of recursive factorial, all right? + +823 +00:53:02,880 --> 00:53:07,220 +So, here's fact-recursive, or standard factorial definition. + +824 +00:53:07,220 --> 00:53:09,910 +We said this one is still a recursive procedure, + +825 +00:53:09,910 --> 00:53:13,750 +but this is actually a recursive process. + +826 +00:53:13,750 --> 00:53:16,566 +And then, just to link it back to the way we started, + +827 +00:53:16,566 --> 00:53:20,530 +we said oh, you can see that it's going to be recursive process + +828 +00:53:20,530 --> 00:53:22,122 +by the substitution model + +829 +00:53:22,122 --> 00:53:30,450 +because, if I say recursive factorial of 5, + +830 +00:53:30,450 --> 00:53:36,000 +that turns into 5 times-- + +831 +00:53:36,000 --> 00:53:37,989 +what is it, fact-rec, or record fact-- + +832 +00:53:42,620 --> 00:53:54,230 +5 times recursive factorial of 4, which turns into 5 times 4 + +833 +00:53:54,230 --> 00:54:08,090 +times fact-rec of 3, which returns into 5 times 4 times 3 + +834 +00:54:08,090 --> 00:54:15,240 +times, and so on, right? + +835 +00:54:15,240 --> 00:54:18,100 +The idea is there was this chain of stuff building up, + +836 +00:54:18,100 --> 00:54:21,520 +which justified, in the substitution model, the fact that it's recursive. + +837 +00:54:21,520 --> 00:54:24,180 +And now, let's actually see that chain of stuff build up + +838 +00:54:24,180 --> 00:54:27,465 +and where it is in the machine, OK? + +839 +00:54:27,465 --> 00:54:30,230 +All right, well, let's imagine we're going to start out again. + +840 +00:54:30,230 --> 00:54:41,451 +We'll tell it to evaluate recursive factorial of 5 + +841 +00:54:41,451 --> 00:54:45,000 +in some environment, again, E,0 + +842 +00:54:45,000 --> 00:54:49,275 +where recursive factorial is defined, OK? + +843 +00:54:49,275 --> 00:54:52,490 +Well, now we know what's eventually going to happen. + +844 +00:54:52,490 --> 00:54:53,925 +This is going to come along, + +845 +00:54:53,925 --> 00:54:57,071 +it'll evaluate those things, figure out it's a procedure, + +846 +00:54:57,071 --> 00:55:00,255 +build somewhere over here an environment, E,1, + +847 +00:55:00,255 --> 00:55:06,725 +which has n bound to 5, which hangs off of E,0, + +848 +00:55:07,800 --> 00:55:10,847 +which would be, presumably, the definition environment + +849 +00:55:10,847 --> 00:55:12,847 +of recursive factorial, OK? + +850 +00:55:14,610 --> 00:55:19,670 +And, in this environment, it's going to go off and evaluate the body. + +851 +00:55:19,670 --> 00:55:27,000 +So, again, the evaluation here will reduce to + +852 +00:55:27,000 --> 00:55:29,950 +evaluating the body in E,1. + +853 +00:55:29,950 --> 00:55:33,530 +That's going to look at an if, and I won't go through the details of if. + +854 +00:55:33,530 --> 00:55:34,880 +It'll look at the predicate. + +855 +00:55:34,880 --> 00:55:37,840 +It'll decide it eventually has to evaluate the alternative. + +856 +00:55:37,840 --> 00:55:41,300 +So this whole thing, again, will reduce to + +857 +00:55:41,300 --> 00:55:47,139 +the alternative of recursive factorial, the alternative clause, + +858 +00:55:47,139 --> 00:55:53,075 +which says that this whole thing reduces to times n + +859 +00:55:53,075 --> 00:56:08,720 +of recursive factorial of n minus 1 in the environment E,1, OK? + +860 +00:56:08,720 --> 00:56:11,200 +So the original expression, now, is going to reduce to + +861 +00:56:11,200 --> 00:56:13,754 +evaluating that expression, all right? + +862 +00:56:13,754 --> 00:56:16,280 +Now we have an application. + +863 +00:56:16,280 --> 00:56:18,225 +We did an application before. + +864 +00:56:18,225 --> 00:56:20,390 +Remember what happens in an application? + +865 +00:56:20,390 --> 00:56:21,975 +The first thing you do is you go off and you + +866 +00:56:21,975 --> 00:56:25,350 +save the value of the continue register on the stack. + +867 +00:56:25,350 --> 00:56:27,365 +So the stack here is going to have done in it. + +868 +00:56:29,980 --> 00:56:35,130 +And then you're going to set up to evaluate the sub-parts, OK? + +869 +00:56:35,130 --> 00:56:37,200 +So here we go off to evaluate the sub-parts. + +870 +00:56:39,375 --> 00:56:41,450 +First thing we're going to do is evaluate the operator. + +871 +00:56:44,490 --> 00:56:47,250 +What happens when we evaluate an operator? + +872 +00:56:47,250 --> 00:56:51,480 +Well, we arrange things so that the operator ends up in the expression register. + +873 +00:56:51,480 --> 00:56:54,630 +The environments in the ENV register continue someplace + +874 +00:56:54,630 --> 00:56:56,590 +where we're going to go evaluate the arguments. + +875 +00:56:56,590 --> 00:56:59,520 +And, on the stack, we've saved the original continue, + +876 +00:56:59,520 --> 00:57:01,720 +which is where we wanted to be when we're all done. + +877 +00:57:01,720 --> 00:57:03,400 +And then the things we needed + +878 +00:57:03,400 --> 00:57:05,807 +when we're going to get done evaluating the operator, + +879 +00:57:05,807 --> 00:57:08,333 +the things we'll need to evaluate the arguments, namely, + +880 +00:57:08,333 --> 00:57:14,000 +the environment and those arguments, those unevaluated arguments, + +881 +00:57:14,000 --> 00:57:15,620 +so there they are sitting on the stack. + +882 +00:57:15,620 --> 00:57:18,370 +And we're about to go off to evaluate the operator. + +883 +00:57:23,130 --> 00:57:26,920 +Well, when we return from this particular call-- + +884 +00:57:26,920 --> 00:57:29,380 +so we're about to call eval-dispatch here-- + +885 +00:57:29,380 --> 00:57:32,730 +when we return from this call, the value of that operator, + +886 +00:57:32,730 --> 00:57:36,275 +which, in this case, is going to be the primitive multiplier procedure, + +887 +00:57:36,275 --> 00:57:42,800 +will end up in the FUN register, all right? + +888 +00:57:42,800 --> 00:57:44,530 +We're going to evaluate some arguments. + +889 +00:57:44,530 --> 00:57:47,730 +They will evaluate n here. + +890 +00:57:47,730 --> 00:57:50,250 +That'll give us 5, in this case. + +891 +00:57:50,250 --> 00:57:52,900 +We're going to put that in the argl register, + +892 +00:57:52,900 --> 00:57:57,460 +and then we'll go off to evaluate the second operand. + +893 +00:57:57,460 --> 00:58:00,365 +So, at the point where we go off to evaluate the second operand-- + +894 +00:58:00,365 --> 00:58:03,633 +and I'll skip details like computing, and minus 1, and all of that-- + +895 +00:58:03,633 --> 00:58:06,385 +but, when we go off to evaluate the second operand, + +896 +00:58:06,385 --> 00:58:10,737 +that will eventually reduce to another call to fact-recursive. + +897 +00:58:12,000 --> 00:58:16,525 +And, what we've got on the stack here is + +898 +00:58:16,525 --> 00:58:19,942 +the operator from that combination that we're going to use it in + +899 +00:58:19,942 --> 00:58:23,790 +and the other argument, OK? + +900 +00:58:23,790 --> 00:58:30,200 +So, now, we're set up for another call to recursive factorial. + +901 +00:58:30,200 --> 00:58:31,438 +And, when we're done with this one, + +902 +00:58:31,438 --> 00:58:33,935 +we're going to go to accumulate the last arg. + +903 +00:58:33,935 --> 00:58:35,200 +And remember what that'll do? + +904 +00:58:35,200 --> 00:58:36,425 +That'll say oh, + +905 +00:58:36,425 --> 00:58:36,450 +whatever the result of this has to get combined with that, + +906 +00:58:36,450 --> 00:58:39,281 +whatever the result of this has to get combined with that, + +907 +00:58:39,281 --> 00:58:41,690 +and we're going to multiply them. + +908 +00:58:41,690 --> 00:58:45,720 +But, notice now, we're at another recursive factorial. + +909 +00:58:45,720 --> 00:58:49,325 +We're about to call eval-dispatch again, + +910 +00:58:49,325 --> 00:58:53,700 +except we haven't really reduced it because there's stuff on the stack now. + +911 +00:58:53,700 --> 00:58:55,244 +The stuff on the stack says oh, when you get back, + +912 +00:58:55,244 --> 00:58:58,430 +you'd better multiply it by the 5 you had hanging there. + +913 +00:58:58,430 --> 00:59:07,125 +So, when we go off to make another call, + +914 +00:59:07,125 --> 00:59:09,300 +we evaluate the n minus 1. + +915 +00:59:09,300 --> 00:59:11,256 +That gives us another environment + +916 +00:59:11,256 --> 00:59:14,600 +in which the new n's going to be down to 4. + +917 +00:59:14,600 --> 00:59:18,930 +And we're about to call eval-dispatch again, right? + +918 +00:59:18,930 --> 00:59:21,350 +We get another call. + +919 +00:59:21,350 --> 00:59:26,040 +That 4 is going to end up in the same situation. + +920 +00:59:26,040 --> 00:59:30,020 +We'll end up with another call to fact-recursive n. + +921 +00:59:30,020 --> 00:59:32,684 +And sitting on the stack will be the stuff from the original one + +922 +00:59:32,684 --> 00:59:35,360 +and, now, the subsidiary one we're doing. + +923 +00:59:35,360 --> 00:59:36,910 +And both of them are waiting for the same thing. + +924 +00:59:36,910 --> 00:59:40,600 +They're going to go to accumulate a last argument. + +925 +00:59:40,600 --> 00:59:43,258 +And then, of course, when we go to the fourth call, + +926 +00:59:43,258 --> 00:59:45,640 +the same thing happens, right? + +927 +00:59:45,640 --> 00:59:47,300 +And this goes on, and on, and on. + +928 +00:59:47,300 --> 00:59:50,075 +And what you see here on the stack, + +929 +00:59:50,107 --> 00:59:52,225 +exactly what's sitting here on the stack, + +930 +00:59:52,225 --> 00:59:54,960 +the thing that says times and 5. + +931 +00:59:54,960 --> 01:00:00,470 +And what you're going to do with that is accumulate that into a last argument. + +932 +01:00:00,470 --> 01:00:02,760 +That's exactly this, right? + +933 +01:00:02,760 --> 01:00:05,650 +This is exactly where that stuff is hanging. + +934 +01:00:05,650 --> 01:00:11,659 +Effectively, the operator you're going to apply, + +935 +01:00:11,659 --> 01:00:13,625 +the other argument + +936 +01:00:13,672 --> 01:00:15,300 +that it's got to be multiplied by when you get back + +937 +01:00:15,300 --> 01:00:16,879 +and the parentheses, + +938 +01:00:16,879 --> 01:00:19,620 +which says yeah, what you wanted to do was accumulate them. + +939 +01:00:19,620 --> 01:00:22,560 +So, you see, the substitution model is not such a lie. + +940 +01:00:22,560 --> 01:00:27,198 +That really is, in some sense, what's sitting right on the stack. + +941 +01:00:27,198 --> 01:00:29,046 +OK. + +942 +01:00:29,046 --> 01:00:33,260 +All right, so that, in some sense, should explain for you, + +943 +01:00:33,260 --> 01:00:36,596 +or at least convince you, that, + +944 +01:00:36,596 --> 01:00:39,870 +somehow, this evaluator is managing + +945 +01:00:39,870 --> 01:00:42,959 +to take these procedures and execute some of them iteratively + +946 +01:00:42,959 --> 01:00:46,410 +and some of them recursively, even though, + +947 +01:00:46,410 --> 01:00:49,215 +as syntactically, they look like recursive procedures. + +948 +01:00:49,215 --> 01:00:50,660 +How's it managing to do that? + +949 +01:00:50,660 --> 01:00:53,725 +Well, the basic reason it's managing to do that + +950 +01:00:53,725 --> 01:01:01,090 +is the evaluator is set up to save only what it needs later. + +951 +01:01:01,090 --> 01:01:04,670 +So, for example, at the point where you've reduced + +952 +01:01:04,670 --> 01:01:07,683 +evaluating an expression and an environment + +953 +01:01:07,683 --> 01:01:10,525 +to applying a procedure to some arguments, + +954 +01:01:10,525 --> 01:01:13,375 +it doesn't need that original environment anymore + +955 +01:01:13,375 --> 01:01:17,675 +because any environment stuff will be packaged inside the procedures + +956 +01:01:17,675 --> 01:01:20,160 +where the application's going to happen. + +957 +01:01:20,160 --> 01:01:23,656 +All right, similarly, when you're going along evaluating an argument list, + +958 +01:01:23,656 --> 01:01:25,910 +when you've finished evaluating the list, + +959 +01:01:25,910 --> 01:01:28,200 +when you're finished evaluating the last argument, + +960 +01:01:28,200 --> 01:01:31,500 +you don't need that argument list any more, right? + +961 +01:01:31,500 --> 01:01:32,941 +And you don't need the environment where + +962 +01:01:32,941 --> 01:01:36,690 +those arguments would be evaluated, OK? + +963 +01:01:36,690 --> 01:01:40,890 +So the basic reason that this interpreter is being so smart + +964 +01:01:40,890 --> 01:01:43,050 +is that it's not being smart at all, it's being stupid. + +965 +01:01:43,050 --> 01:01:46,010 +It's just saying I'm only going to save what I really need. + +966 +01:01:48,700 --> 01:01:51,000 +Well, let me show you here. + +967 +01:01:54,880 --> 01:01:58,310 +Here's the actual thing that's making a tail recursive. + +968 +01:01:58,310 --> 01:02:00,135 +Remember, it's the restore of continue. + +969 +01:02:00,135 --> 01:02:08,800 +It's saying when I go off to evaluate the procedure body, + +970 +01:02:08,800 --> 01:02:11,252 +I should tell eval to come back to + +971 +01:02:11,252 --> 01:02:15,170 +the place where that original evaluation was supposed to come back to. + +972 +01:02:15,170 --> 01:02:17,700 +So, in some sense, you want to say what's the actual line + +973 +01:02:17,700 --> 01:02:18,770 +that makes a tail recursive? + +974 +01:02:18,770 --> 01:02:19,920 +It's that one. + +975 +01:02:19,920 --> 01:02:23,680 +If I wanted to build a non-tail recursive evaluator, + +976 +01:02:23,680 --> 01:02:27,124 +for some strange reason, all I would need to do is, + +977 +01:02:27,124 --> 01:02:32,750 +instead of restoring continue at this point, I'd set up a label down here + +978 +01:02:32,750 --> 01:02:37,455 +called, "Where to come back after you've finished applying the procedure." + +979 +01:02:37,455 --> 01:02:39,920 +Instead, I'd set continue to that. + +980 +01:02:39,920 --> 01:02:41,299 +I'd go to eval-dispatch, + +981 +01:02:41,299 --> 01:02:43,790 +and then eval-dispatch would come back here. + +982 +01:02:43,790 --> 01:02:47,920 +At that point, I would restore continue and go to the original one. + +983 +01:02:47,920 --> 01:02:51,075 +So here, the only consequence of that + +984 +01:02:51,075 --> 01:02:52,840 +would be to make it non-tail recursive. + +985 +01:02:52,840 --> 01:02:54,629 +It would give you exactly the same answers, + +986 +01:02:54,629 --> 01:02:56,656 +except if you did that iterative factorial + +987 +01:02:56,656 --> 01:02:59,875 +and all those iterative procedures, it would execute recursively. + +988 +01:03:02,900 --> 01:03:05,760 +Well, I lied to you a little bit, but just a little bit, + +989 +01:03:05,760 --> 01:03:08,550 +because I showed you a slightly over-simplified evaluator + +990 +01:03:08,550 --> 01:03:11,225 +where it assumes that each procedure -- + +991 +01:03:11,225 --> 01:03:13,890 +each procedure body has only one expression. + +992 +01:03:13,890 --> 01:03:17,870 +Remember, in general, a procedure has a sequence of expressions in it. + +993 +01:03:17,870 --> 01:03:20,490 +So there's nothing really conceptually new. + +994 +01:03:20,490 --> 01:03:22,725 +Let me just show you the actual evaluator + +995 +01:03:22,725 --> 01:03:24,730 +that handles sequences of expressions. + +996 +01:03:28,470 --> 01:03:32,075 +This is compound-apply now, and the only difference from the old one + +997 +01:03:32,075 --> 01:03:35,980 +is that, instead of going off to eval directly, + +998 +01:03:35,980 --> 01:03:38,039 +it takes the whole body of the procedure, + +999 +01:03:38,039 --> 01:03:40,151 +which, in this case, is a sequence of expressions, + +1000 +01:03:40,151 --> 01:03:42,325 +and goes off to eval-sequence. + +1001 +01:03:42,325 --> 01:03:47,907 +And eval-sequence is a little loop that, basically, + +1002 +01:03:47,907 --> 01:03:49,980 +does these evaluations one at a time. + +1003 +01:03:52,630 --> 01:03:53,900 +So it does an evaluation. + +1004 +01:03:53,900 --> 01:03:58,440 +Says oh, when I come back, I'd better come back here to do the next one. + +1005 +01:03:58,440 --> 01:04:01,038 +And, when I'm all done, when I want to get the last expression, + +1006 +01:04:01,038 --> 01:04:06,410 +I just restore my continue and go off to eval-dispatch. + +1007 +01:04:06,410 --> 01:04:08,200 +And, again, if you wanted for some reason to + +1008 +01:04:08,200 --> 01:04:10,492 +break tail recursion in this evaluator, + +1009 +01:04:10,492 --> 01:04:14,900 +all you need to do is not handle the last expression, especially. + +1010 +01:04:14,900 --> 01:04:17,247 +Just say, after you've done the last expression, + +1011 +01:04:17,247 --> 01:04:21,900 +come back to some other place after which you restore continue. + +1012 +01:04:21,900 --> 01:04:26,550 +And, for some reason, a lot of LISP evaluators tended to work that way. + +1013 +01:04:26,550 --> 01:04:28,545 +And the only consequence of that is that + +1014 +01:04:28,545 --> 01:04:31,614 +iterative procedures built up stack. + +1015 +01:04:31,614 --> 01:04:35,670 +And it's not clear why that happened. + +1016 +01:04:35,670 --> 01:04:36,210 +All right. + +1017 +01:04:36,210 --> 01:04:38,095 +Well, let me just sort of summarize, + +1018 +01:04:38,095 --> 01:04:41,120 +since this is a lot of details in a big program. + +1019 +01:04:41,120 --> 01:04:44,040 +But the main point is that it's no different, + +1020 +01:04:44,040 --> 01:04:47,060 +conceptually, from translating any other program. + +1021 +01:04:47,060 --> 01:04:50,156 +And the main idea is that we have this universal evaluator program, + +1022 +01:04:50,156 --> 01:04:51,870 +the meta-circular evaluator. + +1023 +01:04:51,870 --> 01:04:54,560 +If we translate that into LISP, then we have all of LISP. + +1024 +01:04:54,560 --> 01:04:57,980 +And that's all we did, OK? + +1025 +01:04:57,980 --> 01:04:59,680 +The second point is that the magic's gone away. + +1026 +01:04:59,680 --> 01:05:01,970 +There should be no more magic in this whole system, right? + +1027 +01:05:01,970 --> 01:05:08,720 +In principle, it should all be very clear except, maybe, for + +1028 +01:05:08,720 --> 01:05:10,940 +how list structured memory works, and + +1029 +01:05:10,940 --> 01:05:12,640 +we'll see that later. + +1030 +01:05:12,640 --> 01:05:15,450 +But that's not very hard. + +1031 +01:05:15,450 --> 01:05:18,720 +The third point is that all this tail recursion came from + +1032 +01:05:18,720 --> 01:05:22,550 +the discipline of eval being very careful + +1033 +01:05:22,550 --> 01:05:25,870 +to save only what it needs next time. + +1034 +01:05:25,870 --> 01:05:28,180 +It's not some arbitrary thing where we're saying well, + +1035 +01:05:28,180 --> 01:05:29,864 +whenever we call a sub-routine, + +1036 +01:05:29,864 --> 01:05:33,940 +we'll save all the registers in the world and come back, right? + +1037 +01:05:33,940 --> 01:05:37,150 +See, sometimes it pays to really worry about efficiency. + +1038 +01:05:37,150 --> 01:05:40,459 +And, when you're down in the guts of your evaluator machine, + +1039 +01:05:40,459 --> 01:05:42,560 +it really pays to think about things like that + +1040 +01:05:42,560 --> 01:05:45,230 +because it makes big consequences. + +1041 +01:05:45,230 --> 01:05:47,842 +Well, I hope what this has done + +1042 +01:05:47,842 --> 01:05:52,560 +is really made the evaluator seem concrete, right? + +1043 +01:05:52,560 --> 01:05:56,631 +I hope you really believe that somebody could hold a LISP + +1044 +01:05:56,631 --> 01:05:59,075 +LISP evaluator in the palm of their hand. + +1045 +01:05:59,075 --> 01:06:02,540 +Maybe to help you believe that, here's a LISP evaluator + +1046 +01:06:02,540 --> 01:06:06,160 +that I'm holding the palm of my hand, right? + +1047 +01:06:06,160 --> 01:06:10,738 +And this is a chip which is actually + +1048 +01:06:10,738 --> 01:06:13,700 +quite a bit more complicated than the evaluator I showed you. + +1049 +01:06:17,815 --> 01:06:19,200 +Maybe, here's a better picture of it. + +1050 +01:06:22,070 --> 01:06:24,730 +What there is, is you can see the same overall structure. + +1051 +01:06:24,730 --> 01:06:26,940 +This is a register array. + +1052 +01:06:26,940 --> 01:06:27,910 +These are the data paths. + +1053 +01:06:27,910 --> 01:06:29,800 +Here's a finite state controller. + +1054 +01:06:29,800 --> 01:06:32,810 +And again, finite state, that's all there is. + +1055 +01:06:32,810 --> 01:06:34,160 +And somewhere there's external memory + +1056 +01:06:34,160 --> 01:06:35,750 +that'll worry about things. + +1057 +01:06:35,750 --> 01:06:37,552 +And this particular one is very complicated + +1058 +01:06:37,552 --> 01:06:39,664 +because it's trying to run LISP fast. + +1059 +01:06:39,664 --> 01:06:42,976 +And it has some very, very fast parallel operations in there + +1060 +01:06:42,976 --> 01:06:46,650 +like, if you want to index into an array, + +1061 +01:06:46,650 --> 01:06:50,362 +simultaneously check that the index is an integer, + +1062 +01:06:50,362 --> 01:06:52,863 +check that it doesn't exceed the array bands, + +1063 +01:06:52,863 --> 01:06:57,120 +and go off and do the memory access, and do all those things simultaneously. + +1064 +01:06:57,120 --> 01:06:58,970 +And then, later, if they're all OK, actually + +1065 +01:06:58,970 --> 01:07:00,420 +get the value there. + +1066 +01:07:00,420 --> 01:07:02,327 +So there are a lot of complicated operations + +1067 +01:07:02,327 --> 01:07:06,550 +in these data paths for making LISP run in parallel. + +1068 +01:07:06,550 --> 01:07:10,640 +It's a completely non-risk philosophy of evaluating LISP. + +1069 +01:07:10,640 --> 01:07:13,740 +And then, this microcode is pretty complicated. + +1070 +01:07:13,740 --> 01:07:17,740 +Let's see, there's what? + +1071 +01:07:17,740 --> 01:07:24,079 +There's about 389 instructions of 220-bit microcode sitting here + +1072 +01:07:24,079 --> 01:07:27,940 +because these are very complicated data paths. + +1073 +01:07:27,940 --> 01:07:33,580 +And the whole thing has about 89,000 transistors, OK? + +1074 +01:07:33,580 --> 01:07:33,840 +OK. + +1075 +01:07:33,840 --> 01:07:37,970 +Well, I hope that that takes away a lot of the mystery. + +1076 +01:07:37,970 --> 01:07:39,240 +Maybe somebody wants to look at this. + +1077 +01:07:42,048 --> 01:07:43,298 +Yeah. + +1078 +01:07:46,260 --> 01:07:46,480 +OK. + +1079 +01:07:46,480 --> 01:07:47,730 +Let's stop. + +1080 +01:07:55,890 --> 01:07:57,815 +Questions? + +1081 +01:07:57,815 --> 01:08:00,420 +AUDIENCE: OK, now, it sounds like what you're saying is that, + +1082 +01:08:00,420 --> 01:08:04,600 +with the restore continue put in the proper place, that + +1083 +01:08:04,600 --> 01:08:09,422 +procedures that would invoke a recursive process + +1084 +01:08:09,422 --> 01:08:12,675 +now invoke an integer process + +1085 +01:08:12,675 --> 01:08:15,165 +just by the way that the eval signature is? + +1086 +01:08:15,165 --> 01:08:17,549 +PROFESSOR: I think the way I'd prefer to put it is that, + +1087 +01:08:17,549 --> 01:08:20,557 +with restore continue put in the wrong place, + +1088 +01:08:20,557 --> 01:08:25,880 +you can cause any syntactically-looking recursive procedure, in fact, + +1089 +01:08:25,880 --> 01:08:28,029 +to build up stack as it runs. + +1090 +01:08:28,029 --> 01:08:33,150 +But there's no reason for that, + +1091 +01:08:33,150 --> 01:08:35,660 +so you might want to play around with it. + +1092 +01:08:35,660 --> 01:08:38,185 +You can just switch around two or three instructions + +1093 +01:08:38,185 --> 01:08:41,129 +in the way compound-apply comes back, + +1094 +01:08:41,129 --> 01:08:45,060 +and you'll get something which isn't tail recursive. + +1095 +01:08:45,060 --> 01:08:47,670 +But the thing I wanted to emphasize is there's no magic. + +1096 +01:08:47,670 --> 01:08:52,455 +It's not as if there's some very clever pre-processing program + +1097 +01:08:52,455 --> 01:08:57,425 +that's looking at this procedure, factorial iter, and say oh, gee, + +1098 +01:08:57,425 --> 01:09:01,060 +I really notice that I don't have to push stack in order to do this. + +1099 +01:09:01,060 --> 01:09:03,760 +Some people think that that's what's going on. + +1100 +01:09:03,760 --> 01:09:05,383 +It's something much, much more dumb than that, + +1101 +01:09:05,383 --> 01:09:08,880 +it's this one place you're putting the restore instruction. + +1102 +01:09:08,880 --> 01:09:10,353 +It's just automatic. + +1103 +01:09:10,353 --> 01:09:11,603 +AUDIENCE: OK. + +1104 +01:09:14,217 --> 01:09:17,850 +AUDIENCE: But that's not affecting the time complexity is it? + +1105 +01:09:17,850 --> 01:09:18,275 +PROFESSOR: No. + +1106 +01:09:18,275 --> 01:09:21,810 +AUDIENCE: It's just that it's handling it recursively + +1107 +01:09:21,810 --> 01:09:23,020 +instead of iteratively. + +1108 +01:09:23,020 --> 01:09:27,179 +But, in terms of the order of time it takes to finish the operation, + +1109 +01:09:27,179 --> 01:09:29,220 +it's the same one way or the other, right? + +1110 +01:09:29,220 --> 01:09:29,920 +PROFESSOR: Yes. + +1111 +01:09:29,920 --> 01:09:32,609 +Tail recursion is not going to change the time complexity of anything + +1112 +01:09:32,609 --> 01:09:36,029 +because, in some sense, it's the same algorithm that's going on. + +1113 +01:09:36,029 --> 01:09:41,210 +What it's doing is really making this thing run as an iteration, right? + +1114 +01:09:41,210 --> 01:09:44,750 +Not going to run out of memory counting up to a giant number + +1115 +01:09:44,750 --> 01:09:47,683 +simply because the stack would get pushed. + +1116 +01:09:47,683 --> 01:09:51,640 +See, the thing you really have to believe is that, when we write-- + +1117 +01:09:51,640 --> 01:09:53,781 +see, we've been writing all these things called iterations, + +1118 +01:09:53,781 --> 01:09:57,990 +infinite loops, define loop to be called loop. + +1119 +01:10:00,325 --> 01:10:03,650 +That's is as much an iteration + +1120 +01:10:03,650 --> 01:10:07,630 +as if we wrote do forever loop, right? + +1121 +01:10:07,630 --> 01:10:09,280 +It's just syntactic sugar as the difference. + +1122 +01:10:09,280 --> 01:10:14,730 +These things are real, honest to god, iterations, right? + +1123 +01:10:14,730 --> 01:10:16,681 +They don't change the time complexity, but they + +1124 +01:10:16,681 --> 01:10:18,535 +turn them into real iterations. + +1125 +01:10:21,686 --> 01:10:23,800 +All right, thank you. +