1 00:00:05,870 --> 00:00:10,550 Sometimes the function that you want to pass to an abstract function, the 2 00:00:10,550 --> 00:00:16,040 function you're passing as an argument, doesn't exist yet. 3 00:00:17,510 --> 00:00:22,590 In those cases, you could always define it with Local if you want to. 4 00:00:22,590 --> 00:00:26,390 But there's a very interesting subcase where you must define it with Local. 5 00:00:27,460 --> 00:00:30,430 That's what we're going to look at in this video, is what to do when the 6 00:00:30,430 --> 00:00:34,890 function you want to pass to an abstract function doesn't yet exist. 7 00:00:36,210 --> 00:00:40,660 I mean, closure started at Racket. And this file is like built in starter, 8 00:00:40,660 --> 00:00:44,260 in that it defines five images for us to use, and it defines a list of those 9 00:00:44,260 --> 00:00:49,332 images. But it doesn't define those functions 10 00:00:49,332 --> 00:00:54,120 like wide and tall. Those predicates aren't defined in here. 11 00:00:54,120 --> 00:00:56,804 So in some sense, what's going to happen in the problems we deal with is we're 12 00:00:56,804 --> 00:01:01,870 going to wish we had those predicates. And we'll have to define them and others. 13 00:01:01,870 --> 00:01:06,384 The rest of the file has problems, again similar to those in using built in 14 00:01:06,384 --> 00:01:10,732 starter. But the difference here is that I've got 15 00:01:10,732 --> 00:01:16,840 all the way to the template stage. Just to get us going more quickly. 16 00:01:16,840 --> 00:01:19,589 So wide only is the function we saw before. 17 00:01:20,790 --> 00:01:23,690 We're supposed to use a list of only those images that have their width 18 00:01:23,690 --> 00:01:28,400 greater than their height. And here's the check-expect, and there's 19 00:01:28,400 --> 00:01:33,104 the stub, and here's the template. I've got the template, commented out, so 20 00:01:33,104 --> 00:01:39,060 that I can run all of the tests. So now we say we're going to go forward. 21 00:01:39,060 --> 00:01:42,310 Here we've got the template. Now, what do we put in the dots? 22 00:01:43,670 --> 00:01:47,025 What do we put in the dots? Well, we don't have wide, question mark, 23 00:01:47,025 --> 00:01:49,485 anymore. We don't have the function we need to put 24 00:01:49,485 --> 00:01:53,412 in the dots. So lemme show you kind of the full way 25 00:01:53,412 --> 00:01:59,877 you want to do this. You kind of want to say something like, 26 00:01:59,877 --> 00:02:06,892 well, if, if each image is i, then what I'm trying to say is, is, the width of 27 00:02:06,892 --> 00:02:14,137 that image greater than The height of that image, that's kind of where I wish I 28 00:02:14,137 --> 00:02:23,474 could put there. But I can't put that there, I have to put 29 00:02:23,474 --> 00:02:26,260 a function there. But that's kind of what I wish I could 30 00:02:26,260 --> 00:02:27,870 put. So what will I do? 31 00:02:27,870 --> 00:02:31,963 Well, I'll make myself a function. And since this is a relatively simple 32 00:02:31,963 --> 00:02:35,302 function and we're pretty far along in the course, I'm going to define it using 33 00:02:35,302 --> 00:02:43,333 local. [NOISE] And now that I've defined that 34 00:02:43,333 --> 00:02:54,220 function using Local, I can just put It there. 35 00:02:54,220 --> 00:02:59,640 I'll just put wide question mark there. And now I've managed to say what I think 36 00:02:59,640 --> 00:03:02,015 I want to say. I've got this function Let me change its 37 00:03:02,015 --> 00:03:05,050 line breaking a little bit to make it a bit more standard. 38 00:03:05,050 --> 00:03:08,059 I could change its line breaking a bit more to make it a bit more easier to 39 00:03:08,059 --> 00:03:09,799 read. Let's try that. 40 00:03:09,799 --> 00:03:15,170 Now I've got some failing tests, but I think those are farther on in the file. 41 00:03:15,170 --> 00:03:18,810 And they are. The test for wide only is succeeding. 42 00:03:18,810 --> 00:03:24,630 So that function's done. So the big idea here was, hey, you know, 43 00:03:24,630 --> 00:03:29,130 the function that I need to pass to filter doesn't exist yet, that's not a 44 00:03:29,130 --> 00:03:34,994 problem, I'll just define it. And since it's a super simple function 45 00:03:34,994 --> 00:03:38,699 and it's pretty far along in the course, I'll define it using local rather than 46 00:03:38,699 --> 00:03:44,470 defining it as a top level function and going through the whole design recipe. 47 00:03:45,530 --> 00:03:49,312 But remember, remember, remember, remember The design recipe is there to 48 00:03:49,312 --> 00:03:53,395 help you not hinder you. If you're not sure how to design the y 49 00:03:53,395 --> 00:03:57,611 question mark function, then do design at top level and do follow the whole recipe 50 00:03:57,611 --> 00:04:02,760 and work the whole thing through so that you get it right. 51 00:04:03,970 --> 00:04:07,625 If, on the other hand, you see what y question mark has to be really easily. 52 00:04:07,625 --> 00:04:12,310 Define it with local. Let's keep going. 53 00:04:12,310 --> 00:04:14,750 This next case is going to be a little bit different. 54 00:04:16,850 --> 00:04:21,660 Now I want a function called wider than only that consumes a number and a list of 55 00:04:21,660 --> 00:04:28,140 image and produces a list of only those images in the list. 56 00:04:28,140 --> 00:04:34,689 With width greater than w. So if I say wider than only 40, LOI one, 57 00:04:34,689 --> 00:04:41,305 I only get i four and i five. Because if we go up here to look at LOI 58 00:04:41,305 --> 00:04:48,001 one, only i four and i five have width greater than 40. 59 00:04:49,240 --> 00:04:55,490 Let's pop back down here, to wider-than-only. 60 00:04:55,490 --> 00:04:59,010 I'll comment out the stub, I'll uncomment the template, now what are we going to 61 00:04:59,010 --> 00:05:04,752 put here? Clearly it's a filter what goes here? 62 00:05:07,180 --> 00:05:14,215 Well what goes here is something like, let's see, it's something like, greater, 63 00:05:14,215 --> 00:05:21,610 image, width of i, assuming again that the image is i, w. 64 00:05:21,610 --> 00:05:27,001 It's something like that. And now this case has a very important 65 00:05:27,001 --> 00:05:30,990 property. And the property is this. 66 00:05:30,990 --> 00:05:36,494 The body of the function that I need to pass to filter, the body of the function 67 00:05:36,494 --> 00:05:43,260 that I pass to filter is going to be something like this, right? 68 00:05:43,260 --> 00:05:51,250 Notice that this body, refers to A parameter of the enclosing function. 69 00:05:51,250 --> 00:05:55,850 It refers to w here which is a parameter of the enclosing function. 70 00:05:58,400 --> 00:06:02,756 And when you have that property, when the body of a function that you need to pass 71 00:06:02,756 --> 00:06:09,840 to an abstract function makes reference to a parameter of an enclosing function. 72 00:06:09,840 --> 00:06:22,110 Then you must define the function you pass using local, and I'll show you why. 73 00:06:22,110 --> 00:06:30,345 I'll define a predicate wider than, question mark Of i, and that'll be its 74 00:06:30,345 --> 00:06:39,068 body. And I'll put Wider Than there, and I'll 75 00:06:39,068 --> 00:06:44,010 test it. And it is working, I'm pretty sure. 76 00:06:44,010 --> 00:06:46,770 Yes, this is a test for farther down in the file. 77 00:06:46,770 --> 00:06:53,880 So Wider Than is working. Look at what's happening here. 78 00:06:53,880 --> 00:07:01,560 If I do check syntax then the width of i has to be greater than w. 79 00:07:01,560 --> 00:07:06,990 And this w is defined by the enclosing wider than only function. 80 00:07:06,990 --> 00:07:10,266 It's a perimeter of the enclosing wider than only function. 81 00:07:10,266 --> 00:07:15,510 And it can be referred to here because of lexical scoping. 82 00:07:15,510 --> 00:07:20,250 If I tried on the other had- let's try the other approach- if I tried on the 83 00:07:20,250 --> 00:07:25,150 other hand to define wider than at top level. 84 00:07:27,020 --> 00:07:36,142 So I'm taking this Wider Than out of the Local, and I'm defining it out here. 85 00:07:36,142 --> 00:07:45,230 And I'll comment this version out. So now what I'm doing is I'm trying to 86 00:07:45,230 --> 00:07:50,550 define this Wider Than predicate. At top level rather than using local. 87 00:07:50,550 --> 00:07:55,870 And it's just not going to work. It's not going to work because this w 88 00:07:55,870 --> 00:08:04,180 here doesn't xist at top level, this doesn't work. 89 00:08:04,180 --> 00:08:07,380 Let me comment both of these out and go back to this one. 90 00:08:07,380 --> 00:08:16,092 This one works because the w Used in the body of wider-than, this w is a parameter 91 00:08:16,092 --> 00:08:23,662 of the enclosing function. It's the rules of lexical scoping that 92 00:08:23,662 --> 00:08:26,810 let it be used here out here, this w is nothing. 93 00:08:26,810 --> 00:08:31,690 The terminology that we use for this, because we want to use fancy computer 94 00:08:31,690 --> 00:08:36,890 scientist terminology, is that, wider than is what's called a closure, and it 95 00:08:36,890 --> 00:08:45,667 closes over the surrounding value of w. And if you want to see why this works, 96 00:08:45,667 --> 00:08:54,355 let's just try hand stepping. This case will hand step wider than only 97 00:08:54,355 --> 00:08:59,622 40 LOI1. By putting it here I'll cause the stepper 98 00:08:59,622 --> 00:09:03,430 to get to it before any of the check expect. 99 00:09:05,190 --> 00:09:11,170 So we'll step that and let's see, we're defining a bunch of images, so this I'll 100 00:09:11,170 --> 00:09:15,676 do very quickly. There's all the images being defined, 101 00:09:15,676 --> 00:09:20,575 there's the list being defined. Let me make this a little bit bigger so 102 00:09:20,575 --> 00:09:24,380 we can see. Let me make it even a bit bigger. 103 00:09:25,440 --> 00:09:28,220 So now we've got wider than only 40 loi 1. 104 00:09:28,220 --> 00:09:33,836 Loi 1, of course, evaluates to that list. Let's make it even bigger now. 105 00:09:33,836 --> 00:09:38,740 Now we've got wider than only 40 with the list. 106 00:09:38,740 --> 00:09:43,558 So now we've substituted the arguments to wider than only into the body of wider 107 00:09:43,558 --> 00:09:48,568 than only. Notice that w in the body of the 108 00:09:48,568 --> 00:09:55,230 wider-than predicate has been replaced by 40. 109 00:09:55,230 --> 00:10:00,020 In the next step, we have a local, and so we rename and lift. 110 00:10:01,080 --> 00:10:04,880 And look what's happened here. There's this new function, wider than 111 00:10:04,880 --> 00:10:10,961 question mark underscore zero. Which in some sense is a special version 112 00:10:10,961 --> 00:10:19,330 of wider than question mark, for 40. What's happened is the combination of 113 00:10:19,330 --> 00:10:26,775 having a function definition. Inside another function, where the inner 114 00:10:26,775 --> 00:10:31,620 function's body refers to a parameter of the outer function. 115 00:10:31,620 --> 00:10:35,590 That's this closure pattern. The combination of doing that and the 116 00:10:35,590 --> 00:10:42,310 rules for function calling and local make kind of a function factory. 117 00:10:42,310 --> 00:10:47,380 Each time wider than only is called with a particular value for w, a new version 118 00:10:47,380 --> 00:10:52,216 of wider than question mark underscore something will be created that's a 119 00:10:52,216 --> 00:11:00,745 predicate for that particular value of w. And then the rest of it is just a call to 120 00:11:00,745 --> 00:11:04,820 filter operating on each particular image's width. 121 00:11:04,820 --> 00:11:09,363 I won't go into the details for that. So what you're seeing here is, two cases 122 00:11:09,363 --> 00:11:14,049 where the function that you want to pass to an abstract function doesn't already 123 00:11:14,049 --> 00:11:18,662 exist. In the first kind of case, that's wide 124 00:11:18,662 --> 00:11:21,796 only. You can define that function using the 125 00:11:21,796 --> 00:11:24,700 local or you could define that function at top level. 126 00:11:24,700 --> 00:11:30,060 But in the second case, where the body of the function must refer to a parameter of 127 00:11:30,060 --> 00:11:36,489 the outer function, then you must define the function locally. 128 00:11:37,800 --> 00:11:43,480 As what we call a closure. You can't define the function at top 129 00:11:43,480 --> 00:11:47,790 level here, because the w doesn't exist at top level. 130 00:11:47,790 --> 00:11:53,626 The w only exists here inside the outer function. 131 00:11:57,220 --> 00:12:01,612 So this does not work. I've got 2 exercises left in this file 132 00:12:01,612 --> 00:12:05,989 for you to try. 1, the first one, is the non closure 133 00:12:05,989 --> 00:12:11,644 case, the second one is the closure case. Work through those carefully and I think 134 00:12:11,644 --> 00:12:16,820 you'll then be comfortable using local to define the function that you pass. 135 00:12:16,820 --> 00:12:20,864 To built in abstract function.