[MUSIC] This is the first of several segments, where we're going to take what

we already learned about function closures, and discover additional and

powerful programming idiom's that, that semantics's will let us use.

So we know the semantics. We know lexical scope.

We know function closers. And we've already done one of the key

idioms. That is passing functions to iterators.

We're now going to do several more. You see the list here.

And in this segment we're going to focus on this combining functions.

This is going to be writing things like function composition.

So without further ado, how about I just go over to, Emax here and write function

composition for you. So, what I want to do is write function

compose that's going to take in two other functions f and g.

And return a function that, when you call it, just calls, returns f(g,x).

And we can do that, alright? So, f(g,x). And if you call compose with 2 functions,

and get a function back. That function you get back is absolutely

using the semantics for closures. So that when you call it, it can look up

f and g in the environment. That was present back when we defined

this function. Alright.

Function composition is a fundamental idea in mathematics and in computer

science. So, let's take a minute just to study it

a little bit. I like to think of its type as something

that takes. These two arguments, so a function from

alpha to beta, or a to b, if you will, that's the g, and a function from b to c,

that's the f, and returns a function from a to c.

And once you look at the type like that, it's, almost painfully clear, what the

function does. It, it pretty much has to call f of g on,

its argument a here, to eventually return This argument of type C.

Now, just to warn you. If you try this out in ML, you get the

REPL, which has no idea that a is the first letter of the alphabet, and b the

second or anything. returns this type here.

It's missing a couple parentheses and it's used different type variables for

different parts of the type. But I promise you that it's an

absolutely, equivalent type alright. Now it turns out that functioning

composition is nice enough, that it's been provided by ml and it's been

provided as an in-fix operator. The same way plus, is a function that

takes two arguments, but we happen to write it between that arguments.

In ml they took the lower case O, zero, like the, O, like this.

Not zero. O, and said that's the function

composition argument, so you can write f composed with g, and that's exactly the

function we Right up here. So let me show you an example of using

it. I'll start with the old boring way that

doesn't use this. Let's write a function, square root of

absolute value. It's going to take an integer, it's

actually going to have type int arrow real is ml's floating points.

And I'll I want to do Is take the absolute value of I and then convert that

to a real number, because that is what this other library functions, math.sqrt,

requires. All right, so this will work absolutely

fine, but let's write a version that instead uses function composition.

So here's a second version Where I can better express, better indicate to the

person reading my code that what I really am doing is composing three functions.

We could put more parenthesis in here but the order won't actually matter, function

composition is associative. And I'm just now taking the function

return from this higher order function call.

And applying it to i, and now you might notice that this has our standard pattern

of unnecessary function wrapping. So we could express even more clearly and

directly what we're doing by saying that the sqrt-of-abs is the variable, the

value you get by composing Map that square root with Real.fromInt and the

absolute value function. So that's using function composition.

We see that we need closures for this to work out correctly.

What I thought I might do now is point out that as nice as function composition

in that order is in math, we kind of have to end up reading this right to left.

Take the absolute value, convert to a real, then take the square root.

Which is a little bit backwards, especially if you're reading your code in

English, where most programmers are used to reading left to right.

So, in more recent years, a different operator has become more popular.

This is used a lot in f sharp, which is a dialect of ml, and functional programmers

just like to use this a bit as well, And, I've defined it here on the slide, but

I'll think I'll just go back to the code and redefine it for you here.

Now on the slide, and in f sharp, this operator is usually written with the pipe

character, and then the angle bracket. I discovered that in the current version,

of sml mode for emacs that I'm using, using that Pipe character, snarls it up,

and makes it think I'm using a different language feature.

So instead, I'm just going to use exclamation point, angle bracket.

But in either case, we can, make up our own infix operator.

The same way plus, is something that takes it's argument on either side, I'm

going to use this keyword that's kind of fancy and special to ml, it says I want

my own, infix operator, that I want to be written That way, and once I've done

this, which tells it, this is always going to be written between the 2

arguments, I can now define it as a function.

Now, this is And then a function, f, and then calls f with x.

This is really not very interesting semantically, it's just taking a function

and argument, and calling the function with the argument, but by putting the

argument on the left, it lets us write our square root of abs in a way that many

programmers find quite easy to read and pleasant, and it's nothing more than a

program idiom. Just say alright, use our new operator

with i and abs, and that will return abs of i.

And then that result can go to Real.frontInt, so that will get me the

real number that is the absolute value of i.

And then, Math.sqrt. And we call this a pipeline, because it

almost looks like we're setting up a pipe where we start with our.

Number i passing through a sequence of functions combining all that to get the

answer we want. So, that's kind of neat.

That's the pipeline operator. A lot of people like it.

It's not doing anything fancy. It's just programming, once we've defined

it with a very simple high order function.

So, I've showed you function composition in pipelines.

There are certainly more interesting things you can do, with combining

functions. So those are probably the most common.

But let's, let's do some others that we just think might be useful.

So I'm going to define a couple functions here I'm going to call backup functions.

So suppose you took in a function f and g, and what you wanted to do is run f,

but if f wasn't the right thing, then return the result of g.

So we're combining functions. I want to return a new function that

takes x. And what it does, is it turns out f of x,

the way this is written returns an option.

And if that option is none, then I want to call g of x.

Otherwise, if it's sum, let me reformat things here for you.

Sum of, sum argument y, then just return that y.

M'kay. So that kind of makes sense, kind of as a

back up. let me show you what that looks like in

terms of its type. Because that will be nice and revealing

of what's going on. And sure enough, if you look up backup

one, it says f has to be an alpha arrow beta option.You can pass it any type you

want. But the think back has to be an option.

Because we pattern match on it with none in some.

The second argument had, g has to take the same thing that F does

because we might call g with the same acts we called F with.

The result type has to not have the option on it because that's the result of

our entire function just like in the other branch of the case expression, we

return to beta. So in general, if you pass an F, as in

alpha, arrow, beta option and g as in alpha, arrow, beta You will get back, the

parentheses just aren't printed here, an alpha arrow beta.

So, it's like function composition, except we don't compose them.

We either return the result of f with the option stripped off, or we return the

result of g. you might prefer a version that worked

with exceptions instead, so let me just show you that.

I won't, try it out or anything. So this, f and g will both just be alpha

arrow betas. But if f, when called with x raises any

exception using a little pattern matching here in my handle expression.

Then call g of x instead. Alright? And if I show you the type of

that one, we'll see that f no longer, has the return.

Option. So those are a few examples of combining

functions. That's our next closure idiom after

passing data to iterators, functions to iterators with private data, and we'll

move on to our next idiom in the next segment.