# 15-150: Principles of Functional Programming

# Lecture 11: Higher-Order Functions (continued)

We continued our discussion of higher-order functions:

Recall that a *higher order* function is a function that acts
on other functions, either taking them as inputs, or providing them as
return values, or both.

We discussed *combinators*. Combinators are higher-order
functions that lift operations from a type to functions with values in
that type. Combinators may be defined using the pointwise principle.
Currying makes this easy in SML.

We discussed *staging*. Staging takes advantage of the
nested lambda form of a curried function to move parts of a
computation close to the place where the arguments required for the
computation appear. This can save computation time in a function that
can do some of its work as soon as it sees its first argument, for
instance. When called several times with the same first argument and
different second arguments, the function can reuse the results of
these early partial computations, since they are available in the
environment part of the closure associated with the function that
expects the second argument.

We talked about generalizing some higher-order list functions to trees.

### Key Concepts

- Combinator
- Pointwise Principle
- Staging
- Partial Evaluation
- Higher-order Tree Functions

See also again the notes from last time on higher order functions,
particularly for the generalization to trees.