[BLANK_AUDIO]. In this first video on abstraction, we're going to start by going all the way back to the beginning of the course, to remember the original problem that functions with parameters solved for us. Then, we're going to see that we can solve a similar problem in our most recent functions, functions that are very, very similar in large part because they're based on the same template. We're going to be able to pull out the common part of the function into an abstract function, and that's going to make the functions we started writing in the first place much, much shorter. Okay. This is going to be fun. I'm in Parameterization Starter and I'm going to go all the way back to the very beginning of the course, to some of the very first kinds of expressions that we wrote. Back at the beginning, we learned how to write an expression like this first one, which computes the area of a circle of diameter four. And of course, if you do that for the area of a circle of diameter 4, you could also do it for the area of a circle of diameter 6. And then, pretty much immediately, we started to think, wow, this is going to be cumbersome if every time we want to do something slightly different. We have to write a whole new expression. And then we learned about functions. And the idea that because we have two expressions here that vary only in one position, they vary only in the position where the 4 and the 6 appears, we could do the following trick. You could take one of the expressions. Put it up here. Wrap a function definition around it. Let's call it area. Pick a parameter name for the varying position. Let's call it r. [INAUDIBLE] the indentation always, and then replace the specific thing that's in the varying position with r. And then, these expressions can be replaced with the more compact, area 4, in this case. I'll just comment out the other one, and area 6, in that case. [SOUND] We run it, we get the same values as before. And we say that this function is more abstract that the specific expressions because it's more general than the specific expressions. This does the area of a circle of diameter 4. This does one for 6. Those are very specific. This does the area of a circle with any given diameter. That's more general, or as I'm saying we call that more abstract. That was Week 1. Later, we learned how to write functions that operate on lists, and lots of other functions. And at one point, we were writing these two functions. The function that is going to take a list of Quidditch teams and see whether it contains UBC. A function that is going to take a list of Quidditch teams and see whether it contains McGill. And, of course, these functions because of the way we design them based on templates are very, very similar. They only differ in one position. They differ in their names of course, but they really only differ in one position where UBC and McGill are. So we can do the same thing. I'm going to take one of them. And in this case, I'm going to put it below instead of above, that's just a detail. [BLANK_AUDIO] I'm going to think of a more general name. There already is a function here. It's not just an expression, so I'm not going to wrap a function around it. I'm going to think of a more general name. I'll just call it contains. There's one varying position, the position that holds UBC and McGill, so I need a parameter for that position. I'll call it s. Since I renamed the function I have to rename the recursive call. I have to pass the parameter in the recursive call and, and, I have to use the parameter in the varying position. All I did there was exactly the same thing I did for area. And now, of course, I can go back to contains-ubc and contains-mcgill. And I can replace their entire body with just a call to this contains function. [SOUND] UBC is what's in the varying position. And all of this can go away. And I can do the same thing here. And all of this can go away. And when I test it, should work, those tests are passing. Now, I didn't really, this isn't really a complete function design, it doesn't have a signature, it doesn't have a purpose, it doesn't have tests. Because we started from working code and work systematically this way, we ended up with working code. This is a different way of arriving at a function design. A little later, when I show you how to get the signature purpose, and, and tests. What you're going to see is that this way of arriving at a working function design, which is called abstraction from, from examples. You get the function definition first, then you get the tests, then you get the purpose, then you get the signature. It's the opposite order. So, we've got the function definition for now. Let's go do another one. Here's two functions, squares and square roots. They're kind of silly. You might not want these two functions, but what squares does is it takes a listed number, and it produces a list of the squares of those numbers. So if you call it with (list 3 4), you get (list 9 16). And what square roots does is it kind of goes the other way. If you call it with (list 9 16), you get (list 3 4). Now let's look at these two functions closely. They're very, very similar. They differ in their names, but aside from that they only differ in one position. This position here. This one calls square in this position. And this one calls square root in this position. So let's try the same thing again. We'll make a copy of one of the two. We'll put it down here. Now we need to think of a more general name. Now for historical and mathematical and wonderful reasons the name I'm going to choose is map2. We never would've chosen map2. I know that. I'm choosing map2. The reason I'm calling this map2 is that later we'll see that ISL. Already has a built in function that does this. And the name of that function is map. And I'm not allowed to redefine a function name. So I'm using map 2 here. Now, I need a name for this parameter. For the thing that goes there or there. What's a good name for the general thing that those are. When it was two radii, we used r. When it was two strings, we used s. These are two functions. I'll just use fn. We could use anything you want of course. A parameter name can be anything you want. It could be strawberry. But I'm using fn. Now, let's see. I also have to rename the recursion, and I have to pass the parameter in the recursion. And I have to use the parameter at the point of variance. And then I have to take these two and replace their bodies with map2, and then this one is square lon. And here it's map2 and this one is sqrt lon. Let's try that. The tests passed. Some of you, especially the one's who've programmed in other languages. Might be going, wait a minute. What happened? gee. Here we've got a function or a function name, at least. Sqr and sqrt, being passed as a parameter. That's right. Map2 is what's called a higher order function. And what it means to be a higher order function is that it can consume other functions as its arguments. So that's exactly what we're doing here in squares. We're calling map two with two arguments. One is name the function square, and the other is list the numbers And square roots does a similar thing. The great thing in DSL ISL, the teaching languages, is that the way of writing this, the notation that we use to write this, is very simple. You can achieve something like this in almost every programming language. [INAUDIBLE] But there's almost no other programming language in which the notation for doing it is as simple as it is here. That's the first part of the process for producing an abstract function from examples. In the next video, I'm going to continue with how you get Signature, purpose and tests. But this video, we're just going to work on the actual function definition. I've got one more example here of 2 functions, positive only and negative only. And I'd like you to go ahead and do just what I've done here, with those two examples. And I want you to call your abstract function, filter two, that's filter two. Go ahead and do that now and I'll see you in the next video.