Last session we have introduced high order functions as building blocks of programs. High order functions are essential in many functional programming languages. So much so that there's a special form to write them. Which we are going to cover in this session. So the topic of this session is currying, and I do not mean the food with that. You'll find out in a second what that is. For our motivation, let's look again at our summation functions, sumInts, sumCubes, sumFactorials. We could factor out the body of these functions and now simply pass the function to apply to each element in the interval. And the two pounds in the intervals. But there's still repetition. Each of the three functions takes two parameters A and B and then passes them on to the sum functions. Can we get rid of these parameters and thereby become even shorter? To see how that could be done, let's rewrite the sum functions as you see here. So that sum function now takes only a single parameter, F, of type n to n as before, and it returns a function. As its result indicated by this function type here. So how can it return a function as a result? Well, it defines a function in this body, sum F, which takes the two bounds and does the usual computation that you've seen before. And that function sum F will be returned from sum. So sum is now a function that returns another function. In particular, a locally defined function. So if you do that, then we can in fact define sumInts to be simply sum of x, arrow x, sum cubed is sum of the cubing function, and SUM factorial is sum of the fact function. It turns out that these functions, they are just exactly the same as the functions we defined before, and they can applied just like the functions we defined before. So, we could say, SUM cubes one, ten, plus SUM factorials ten, twenty. Next question. In the previous example can we avoid the middleman, sum N, sum cubes, and the like. Can we use directly the general sum function? Of course. We simply write, sum of, in this case cube, and then the bounds one to ten. Let's analyze that a, a little bit more. So sum of cube applies to sum function. To the cube function. And returns the sum of cube's function. Sum of cube is therefore equivalent to sum cubes, and that function is next applied to the arguments one and ten. So what that shows is that function application associates to the left. If we write, sum of cube 110, then that's really the same thing as sum of cube. This expression returns a function and that function then is applied to one and ten. So here's another piece of syntactic sugar. The definition of functions that return functions is so useful in functional programming that we have a syntax for it in skylar. So the A previous definition of sum actually can be written shorter like that. We can just combine the, two parameter lists of the outer function and the nested function and write them one after the other. It would say sum of F int and then comes another parameter list with A and B. And the body of the sum function is very much like it was before. You might ask, well what's the point of doing it that way instead of simply writing the function with three parameters like we did at the beginning? Well the idea is that if you do that then actually you can write sum of, let's say cube, separately. That's a valid expression by itself and you can avoid passing the other arguments. They will arrive in a different parameters list that can be applied later on in a different context. So I've said that functions with multiple parameter lists are syntactic sugar. Let's see how they expand. If you have a function with multiple parameter lists like that, RX1, RXN equals E, where N is greater than zero, that's, in fact, equivalent to taking the first N minus one number of parameter lists. And for the last one, you create a fresh function called G, that takes the last list. Maps it to the body E, and G is the function that gets returned from F. That was exactly the definition we did with sum F when we modeled the sum function that dropped its second parameter list by having the inner function, sum F. Or for short, we can just write an anonymous function. So the, the, the definition up here would also be equivalent to the definition that you see down here, where the last parameter list is, the parameter list of anonymous function that maps to E. Now, if you repeat that process n times, then our original n parameter list function is mapped to a function that has no parameter list at all, but on the right hand side we have n nested anonymous functions. This style of definition in function application where essentially every function is mapped to an expression that consists of anonymous functions, nested anonymous functions, that each take one parameter, is called currying. It's named after its promoter, Haskell Brooks Curry, who was a logician in the twentieth century. It's no coincidence that Haskell Brooks Curry shares his first name with the Haskell programming language. In fact, the, this idea goes back even further to Shawn Finkel and probably Fricke, but the term Currying has stuck. So let's take one more look at types. Given this function, sum f int and with it two arguments, what is its type? The answer would be, it first, it is the function that takes the function's argument, so that would be the argument pipe. And that returns a function, that takes two integers as arguments that would both be those two, and that returns finally an int. So note that functional pipes associate to the right. Here I could have written also. Type like this. So, we take the intuitive function and we return this function, but this blue parenthesis here are actually redundant. Because, in general, at types such as int, arrow int, arrow int is read as int arrow, and then the second pairs of ins are in parenthesis. So we put the parenthesis for function types on the right. Let's do an exercise. We have seen the sum function. Can we write a product function that calculates the product of the values of a function for the points on a given interval? As a second exercise, once you have product can you write factorial in terms of it? And the third part of the exercise would be, can you think of a more general function which generalizes both sum and product? So let's see how we would answer that exercise. I have already opened a new worksheet and given you the product function and the parameters and results it takes. So that's analogous to some product would take a function that goes from end to end into two pounds, which are in ints, and we would return an int. How would we define it? So we would go analogous to sum function. First ask, well, if the bounds are empty, then we want to return the unit value for multiplication. So for sum, the unit value was a zero, but for multiplication, it's a one. So we return a one here. And otherwise, we take f of a, and now times product of f and a, plus one, and b. Let's test it. Oh, forgot the function. Let's take the squares of all. Ints between three and seven. That gives us a value which is hard to check, so let's do a smaller, 144. That looks correct. Let's come to the second part of the exercise. Second part of the exercise was, can we define factorial in terms of product? So let's see how we would do that. You have the factorial, which takes an int. And what would that be? So it would be, the definition would be, it's a multiplication of all numbers between one and m. So it's a product where we pass as the function parameter the identity, and the balance would be one and N. Again let's test that. Factorial of five, would be 120, which is also correct. The third part of the exercise was, can we find a function that generalizes sum and product? Using that function we should be able to express both sum and product. What could that be? Well that function would then be parametrized in the type of mapping that we want to apply, because that was something that was common in some end product, plus the two bounds, plus the two things that differ. The two things that differ were, what was the unit value and what was the combining function with which we combined individual values of f? In fact that what, what we are after is a version of map reduce. We want to have a function, the function f would map values in the interval to new values, and reduce, then would combine them. So let's call this new function map reduce. And what should we get as parameters? Well, it needs to get the f parameter and it needs to get a new parameter called det combine that takes two ints and returns an int. And finally, it needs to have a unit value. We'll call it a zero value, which is an int. So that's the value to return if the interval is empty. And after that, we would have the same thing as before. So we would have the two values of A and B. How would we define it? Well, let's take the definition of product as a template. So if A is greater than B, then what do we return? The zero value. Otherwise, we take F of A, and what we do, we do with F of A, we're neither summing nor multiplying, but we now combine it with the map reduce value of the same three parameters that we had initially. And a + one and b. And it seems I'm missing, apparently. Good. So that was the map reduce example. Let's test it. Well a good way to test it actually would be to say well let's define product in terms of map reduce, because after all, we wanted a function that generalizes both sum and product. So product then would be map reduce. Off. What's the function, the given function? F is the mapping function. The combining function would be a function that takes x and y and returns the product of x and y. And the zero would be one for a product. And we pass the parameters like this. And we delete the previous version of product. Oops. I had, had a problem here, where, let's see what it says. In fact what happened here, we get two errors, which says we have a forward reference, that extends over two definitions of values, reds zero and reds one. If you remembered off the worksheet so far, reds zero and reds one, where the values that named these individual parameters. What happens here is that if you define a function then in fact that function can refer to other functions but only as long as there, that there are no definitions or expressions between two, the two functions. So what we need to do then is move the map reviews up in front of the product. So that we wouldn't have a forward reference anymore. So now the program compiles. And we would get the same value of factorial of 520. So that means that we have substituted a correct definition, or seemingly correct definition, for product. You've seen currying as a way to define functions piecewise, one parameter section after the other. In the next session we are going to take what we've learned with high order functions, in another concrete example.