[MUSIC] This segment of the course is all about first-class functions.
And in this first segment, I just want to give you a little bit of a sense of what
that means, introduce a little bit of a terminology, and actually start by taking
a bit of a step back and asking what is this functional programming stuff that
we've been doing and will continue to do through this segment.
So, functional programming can mean a few different things.
To me, it really is about two concepts that are actually separate.
But for historical and somewhat good reasons, they've been combined together
and we call the result functional programming.
The first we've already studied quite a bit and that's avoiding mutation.
Not using assignment statements, not having data that lives in locations that
can change. We've done a lot of that, we're going to
continue to do that. And we'll even see cases where we don't
want that, where actually mutable state is a reasonable programming idiom.
And then the second thing, which is what this section of the course is all about,
is using functions as values. Passing them around and that sort of
thing, and that'll give you a sense very soon of what we mean by that.
Now, there are a few other things that people often think of when they think of
functional programming and these are not necessarily bad aspects of the definition
of functional programming, if you will. First of all, functional programming
often uses lots of recursion and recursive data structures like lists and
trees and we've seen that in our section so far.
You'll also often see a programming style or even a syntax that's much more
mathematical. the definitions we write down tend to
look much more like the mathematics that we studied in school than other styles of
programming tend to. There is something that some functional
programming languages such as Haskell have, which is laziness.
This is actually a technical term. I'm not saying that anyone is being lazy.
We will study laziness briefly later in the course.
Many courses would emphasize it more than we're going to.
That's just a matter of perspective. And then, there's a lot of definitions
that make a whole lot less sense. sometimes people think that oh, if it's
not object-oriented programming, or it's not C, maybe it's functional programming.
And that's pretty sloppy thinking and we'd like to avoid that one.
Now, once we know what functional programming is, then what is a functional
language? And I've taken to decide that this really
doesn't make a whole lot of sense as a yes or no question.
a functional language is one in which you can do functional programming.
But I think I can do functional programming, as described here, in pretty
much any language. It just might be more or less convenient.
It might be more or less the default. So, to me, a functional language is just
one where functional programming is the easy, natural, conventional way to do it.
All the libraries are generally written in a functional style, and so on.
Alright. So, if this course is not entirely about
functional programming, it's broader than that.
But if that's a big focus and if a big part of functional programming is using
functions as values, it's about time we really got started on that part of the
course. So, a first-class function is, like in
ML, like in many programming languages, a situation where functions can appear and
be used wherever we use other values. Wherever you use numbers or lists or
strings or trees, you could also put functions there.
So, functions can be arguments to other functions.
They can be results of functions. They can be a part of a tuple, you
combine them to variables. You can put them in data type
constructors and so on. So, we're not going to do a lot of code
in this introductory segment, but I thought I would show you just a little
bit of how this really can be done in ML. And, in fact, not using any features that
we didn't already have, just ones we didn't think to use this way.
So, here's two functions. One doubles its argument.
The other increments its argument. That's not very interesting.
But now, let's make a tuple, we're in the tuple,
this is going to be a triple so I'm going to have three parts.
What if in the first part, I put the function double?
So, I'm not calling the function, I'm not passing it an argument, I'm just going to
look double up in the environment, get a function back and put that in the
first part of my tupple. Similarly in the second part, how do I
put increment? And just to contrast the difference
between a function and the result of calling the function what if here I put
double of increment of seven. Now, this third position is going to call
increment with seven, get back eight. Call double with that and get sixteen,
alright? And then, we could even, down here at
about eighteen, we could get out using our old hash one operator that we used
before we learned pattern matching. Hash one of a tuple, that is going to
give back the double function and then we could call it with nine.
So, this is an example of first-class functions because I'm putting functions
in a tuple and then later, I'm pulling them out and using them.
So, let's make sure I got this all right. [SOUND] And show you what the RPL shows
for this. This will be useful to us and this over
here. and sure enough, it says, as we're used
to, double is a function of type int arrow int.
Increment is a function of type arrow int arrow int.
This a_tuple, very interesting.
It is a triple, where the first position holds some function.
The RPL never actually prints out functions, other than to write fn.
The second part is fn and the third part is sixteen, just as I promised.
And the type is a triple int arrow int star int arrow int star int.
And finally, eighteen, where we pulled out the double function from the tuple
and then called it with nine, did actually give us eighteen,
alright? So, that's a little sense of the sort of
thing we'll be doing. And later in this section, after we learn the semantics and
how to use first-class functions, we'll see useful idioms.
The code there was obviously on purpose, just a little bit silly,
okay? So, to finish up, let me just give you a
couple more terms. The most common use of first-class
functions is not putting them in tuples and pulling them out of tuples, although
that can be very useful. The most common is to pass a function as
an argument to another function or as the result of another function.
And when you're doing that, the function that takes or returns other functions is
called a higher-order function. It's just a term.
And higher-order functions are a powerful, powerful idiom for factoring
out common computations and we'll see examples in upcoming segments.
One other term we'll get to later in the section is a function closure.
A function closure is a function that uses bindings from outside the function
definition. Now, how can it do that if it's not an
argument or a local variable, how can it use something?
The same way we always have in ML. Things that are already in the
environment can be used by a function. Once you have first-class functions,
functions being passed around and returned, the way this environment
interacts with the functions is more sophisticated, more interesting, and much
more powerful. We're going to put that off just a bit
and talk about function closures later. So, to me, first-class functions means
functions you can pass around and put anywhere you want.
Function closures means functions that can use things in the environment, not
just arguments and local variables. And these are technically separate
concepts but because functional languages always support both and they're often
used together, use both features together,
these terms are often confused with each other.
And even though it's an important conceptual distinction I'm not going to
harp on the definitions and the terminology because they're so commonly
used incorrectly and it's frankly not that big of a deal.
So, that's our introduction. Hopefully you're excited about the idea
of first-class functions and we'll start learning how to use them for actual
interesting code even in the very next segment.