1 00:00:06,200 --> 00:00:09,640 So the last video ended on kind of an amazing note. 2 00:00:09,640 --> 00:00:13,390 Functions can consume other functions as arguments. 3 00:00:14,460 --> 00:00:19,720 And letting us do that, makes it possible to easily write abstract functions. 4 00:00:21,060 --> 00:00:24,021 And then we can use those abstract functions to write, other functions that 5 00:00:24,021 --> 00:00:27,340 are very short, very simple to write. That's pretty great. 6 00:00:29,100 --> 00:00:32,805 As I said in the last video, you can do this kind of abstraction in any language, 7 00:00:32,805 --> 00:00:36,584 and that's why we're covering it in this course. 8 00:00:36,584 --> 00:00:39,947 But it's almost never going to look as clean and simple as it does in this 9 00:00:39,947 --> 00:00:46,356 language so enjoy it while you got it. What we're going to do in this video is 10 00:00:46,356 --> 00:00:49,540 we're going to take the next couple of steps in the design recipe. 11 00:00:50,650 --> 00:00:54,970 We're going to do now the check-expects and the purpose for these abstract 12 00:00:54,970 --> 00:00:58,476 functions. Remember we're working through the recipe 13 00:00:58,476 --> 00:01:01,921 backwards starting from the working abstract function heading back towards 14 00:01:01,921 --> 00:01:06,036 the signature. [INAUDIBLE] I'm in parametrization-v2, 15 00:01:06,036 --> 00:01:10,586 and I'm where I left off last time where we had gotten the working definition of 16 00:01:10,586 --> 00:01:17,779 contains question mark by abstracting it out of contains-ubc, and contains-mcgill. 17 00:01:18,780 --> 00:01:23,370 Let's work on check-expects. Well, the easiest way to get the 18 00:01:23,370 --> 00:01:26,910 check-expects is to abstract them also from the examples. 19 00:01:28,100 --> 00:01:34,068 One way to do it is to take the check-expects for both other functions. 20 00:01:34,068 --> 00:01:39,700 Copy them all down, and we're not going to use all of them, of course. 21 00:01:39,700 --> 00:01:44,436 Now these calls to contains-ubc and contains-mcgill and the check-expects 22 00:01:44,436 --> 00:01:48,491 have to be replaced with a call to contains. 23 00:01:48,491 --> 00:01:53,080 That's the function we're doing now. Now, I'm going to end up deleting a bunch 24 00:01:53,080 --> 00:01:56,671 of these, but because it can be really troublesome to have a call to one of the 25 00:01:56,671 --> 00:02:02,820 concrete functions, I'm going to go ahead and take the time to rename all of these. 26 00:02:02,820 --> 00:02:06,180 And of course, this is going to have to be a string argument inserted in that 27 00:02:06,180 --> 00:02:11,272 position for all of these. So let's see a base case test contains, 28 00:02:11,272 --> 00:02:14,968 it doesn't matter what we look for, but let's look for UBC in empty, that's still 29 00:02:14,968 --> 00:02:18,386 false. And I only need one base case test, so 30 00:02:18,386 --> 00:02:25,634 that one will go away. [INAUDIBLE] Now, let's look for ubc in 31 00:02:25,634 --> 00:02:29,710 cons McGill empty. That one produces false. 32 00:02:29,710 --> 00:02:37,085 Here we can look for ubc in Cons UBC empty and that one is going to produce 33 00:02:37,085 --> 00:02:42,752 true. And let's see let's get rid of these 34 00:02:42,752 --> 00:02:49,850 other one long cases and let's get a couple of two long cases. 35 00:02:51,170 --> 00:02:53,530 This is, let's see, both of those are one long. 36 00:02:53,530 --> 00:02:57,922 So let's see, if we're looking in there, we produce true that means we were 37 00:02:57,922 --> 00:03:02,530 probably looking for, let's say we were looking for UBC and here let's also be 38 00:03:02,530 --> 00:03:07,646 looking for UBC. But let's have a too long case where we 39 00:03:07,646 --> 00:03:12,630 fail. Let's look for Toronto in that list and 40 00:03:12,630 --> 00:03:20,690 there it will produce false. Now all I did here was to just take the 41 00:03:20,690 --> 00:03:23,826 existing examples and work on them a bit to turn them into examples for the new 42 00:03:23,826 --> 00:03:28,112 function. Another thing you could have done was to 43 00:03:28,112 --> 00:03:30,708 generate examples for the new function kind of from scratch from first 44 00:03:30,708 --> 00:03:34,790 principles. But, in cases particularly where perhaps 45 00:03:34,790 --> 00:03:39,122 the examples are complicated. Taking existing examples that work and 46 00:03:39,122 --> 00:03:43,035 revising them might be a better way to be sure your examples work. 47 00:03:43,035 --> 00:03:47,648 But both approaches would be fine. Well, let's try running these examples, 48 00:03:47,648 --> 00:03:53,347 make sure they do work, and they do. So now, again, working backwards through 49 00:03:53,347 --> 00:03:58,403 the HtDF recipe, we've got, we started with a working function Now we've done 50 00:03:58,403 --> 00:04:02,600 the check-expects. Let's do the purpose. 51 00:04:02,600 --> 00:04:12,368 Well, you know, these were the two less abstract purpose statements we started 52 00:04:12,368 --> 00:04:17,269 out with. And oftentimes that's a good way to 53 00:04:17,269 --> 00:04:21,090 figure out the purpose for a more abstract function. 54 00:04:21,090 --> 00:04:24,970 Although sometimes it's harder to get a purpose for an abstract function. 55 00:04:24,970 --> 00:04:29,110 The reason we're going through the recipe backwards is that paradoxically as we go 56 00:04:29,110 --> 00:04:32,830 back towards the signature each step gets harder and harder with abstract 57 00:04:32,830 --> 00:04:36,730 functions, and the fundamental idea of the recipe was always to do the easiest 58 00:04:36,730 --> 00:04:42,402 thing first. In this case, the purpose is going to 59 00:04:42,402 --> 00:04:47,570 come quite easily for us. It's just going to be produce true if los 60 00:04:47,570 --> 00:04:52,260 includes what? It isn't UBC or McGill. 61 00:04:52,260 --> 00:04:56,145 It's s. [INAUDIBLE] if los contains s, we produce 62 00:04:56,145 --> 00:05:00,875 true, so then I'm done with both of those. 63 00:05:00,875 --> 00:05:05,620 [INAUDIBLE] Okay. Now I would normally do the signature, 64 00:05:05,620 --> 00:05:09,750 but I'm going to save all my signatures to do at the end. 65 00:05:09,750 --> 00:05:13,970 Okay, in video three of this three part series is when we'll do the signature. 66 00:05:13,970 --> 00:05:24,420 I'm going to jump down here and do the map2 case. 67 00:05:24,420 --> 00:05:26,790 Let's see. Let me grab some examples. 68 00:05:26,790 --> 00:05:27,648 You know, this time what I'll do is I'll actually do the examples more from first 69 00:05:27,648 --> 00:05:28,606 principles just so you also see that approach. 70 00:05:28,606 --> 00:05:34,660 It's a recursive function operating on a list. 71 00:05:34,660 --> 00:05:40,540 So base case test is going to come first, check-expect, map2. 72 00:05:40,540 --> 00:05:43,651 Now look in this case even though I'm kind of typing then from scratch, I'm 73 00:05:43,651 --> 00:05:48,090 still going to look at the previous. Concrete uses of map2, okay? 74 00:05:48,090 --> 00:05:53,410 Here, map 2 is being called to square numbers. 75 00:05:53,410 --> 00:05:58,390 Here, map 2 is being called to take the square root of numbers. 76 00:05:58,390 --> 00:06:00,840 So those look like things that map 2 can do. 77 00:06:00,840 --> 00:06:04,420 I'll call it with square and the base case test empty. 78 00:06:04,420 --> 00:06:08,103 I get empty. I'll test that right away. 79 00:06:08,103 --> 00:06:20,991 It's working, let me try another one. Map2 of square, and here we'll say, list 80 00:06:20,991 --> 00:06:28,880 2 and 4. Well that's going to produce list four 81 00:06:28,880 --> 00:06:33,150 and 16. Those are about 14. 82 00:06:33,150 --> 00:06:36,489 It's also good to have a test where we make sure that Map2 uses the function we 83 00:06:36,489 --> 00:06:44,036 gave it. So, let's say, check-expect map2 sqrt. 84 00:06:44,036 --> 00:06:54,003 List 16 and 9 is going to be list. The square root of 16 is 4 and the square 85 00:06:54,003 --> 00:06:58,990 root of 9 is 3. Let's try that. 86 00:07:01,890 --> 00:07:05,760 Now you might be tempted at this point to put in some other examples. 87 00:07:05,760 --> 00:07:09,280 You might be tempted at this point to put in some very different examples. 88 00:07:09,280 --> 00:07:11,930 We'll come to that in the next video when we do signatures. 89 00:07:11,930 --> 00:07:15,200 What we need to do now is to go ahead and do the purpose. 90 00:07:17,210 --> 00:07:21,870 Now let's see. Here. 91 00:07:21,870 --> 00:07:28,086 I'm going to copy the two existing purpose statements but they're not 92 00:07:28,086 --> 00:07:34,220 going to help us as much. [NOISE] If, if I just base it off of 93 00:07:34,220 --> 00:07:38,158 those I might be tempted to write a purpose like 94 00:07:38,158 --> 00:07:40,250 [INAUDIBLE]. 95 00:07:40,250 --> 00:07:44,790 Produce list of square root or, ooh, this was [INAUDIBLE]. 96 00:07:44,790 --> 00:07:47,355 I copied the wrong one here. This was actually square, never mind. 97 00:07:47,355 --> 00:07:52,740 Produce list of square root or square of every number in lon. 98 00:07:52,740 --> 00:07:58,855 And maybe that is the first purpose you write. 99 00:07:58,855 --> 00:08:03,070 But then you say to yourself, gee, could this function, is that all it can do? 100 00:08:03,070 --> 00:08:08,076 Can it be more abstract than that? If you look at the body of this function, 101 00:08:08,076 --> 00:08:14,790 the body of map2, you know, it doesn't say square or square root anywhere in it. 102 00:08:15,910 --> 00:08:19,685 It probably can do more things than that, and maybe here you do an experiment. 103 00:08:19,685 --> 00:08:25,298 Check-expects map2. I don't know. 104 00:08:25,298 --> 00:08:34,020 Let's take the absolute value of list 2 minus 3 4. 105 00:08:34,020 --> 00:08:36,300 That would be list 2 3 4. It does that. 106 00:08:36,300 --> 00:08:44,218 So this isn't it. No. 107 00:08:44,218 --> 00:08:50,730 Let me show you a really good purpose statement for the abstract function map2. 108 00:08:50,730 --> 00:08:56,306 And before I type it let me tell you, the thing about purpose for abstract function 109 00:08:56,306 --> 00:09:01,940 is that it usually a lot of tries to get them right. 110 00:09:01,940 --> 00:09:05,076 This one I'm about to write, I guarantee you the first person who invented map 111 00:09:05,076 --> 00:09:08,630 didn't come up with this on the first try. 112 00:09:08,630 --> 00:09:13,540 What I'm going to write is given FN and list N zero N one dot dot dot. 113 00:09:13,540 --> 00:09:16,160 Produce list FN of N zero FN of N one dot dot dot. 114 00:09:26,290 --> 00:09:29,570 That seems very abstract, and it is. It seems almost mathematical. 115 00:09:29,570 --> 00:09:33,502 Sorry about. Bout that, but, let's look at it, if we 116 00:09:33,502 --> 00:09:39,824 call map2 with sqr and list 2 4 we get back list square of 2, that's 4, and 117 00:09:39,824 --> 00:09:48,070 square of 4, that's 16. If we call map2 with square root and list 118 00:09:48,070 --> 00:09:53,170 16 9 we get back List square root of 16 is four. 119 00:09:53,170 --> 00:09:57,756 Square root of nine is three. If we call map2 with abs, the absolute 120 00:09:57,756 --> 00:10:02,112 value function, and two minus three four we get back the absolute value of two is 121 00:10:02,112 --> 00:10:05,632 two. The absolute value of minus three is 122 00:10:05,632 --> 00:10:08,680 three. The absolute value of four is four. 123 00:10:08,680 --> 00:10:13,790 It is doing exactly this, given a fn and a list of numbers. 124 00:10:13,790 --> 00:10:18,730 It produces the list of the result of calling fun on each number in the list. 125 00:10:18,730 --> 00:10:24,704 So that is a much better purpose statement for the abstract function, 126 00:10:24,704 --> 00:10:29,380 map2. So I'm going to end this video the same 127 00:10:29,380 --> 00:10:34,200 way I ended the last video. Here's filter two. 128 00:10:35,210 --> 00:10:40,605 I want you to do the check-expects and the purpose for filter2, and I'll see you 129 00:10:40,605 --> 00:10:43,520 in the next video.