The function type is one of the most important in modern mathematics. As we have noted, Frege patterned his treatment of logic which we are following on the concept of a function. In some ways this type represents the divide between abstract and concrete mathematics. By quantifying over functions we enter the realm of abstract mathematics. Indeed, the very notion of obtaining a function from an expression is called abstraction.
The day-to-day notation for functions at the beginning of the century was that
one wrote phrases like ``the function sin(x) in x or ex in x''.
Russell's notation,
,
and Church's lambda
notationlambda notation,
,
brought flexibility to
the notation, creating a single name for the function with a binding operator
to indicate the arguments. The modern working notation in
mathematical articles and books (used in Bourbaki for example) is
for a function with argument x and value given by the expression b in
x; for example
for the identity,
for the
exponential.
As we did for propositional functions, we will adopt the lambda notation in the
form
for
.
In Nuprl one can display this
in a variety of ways, including
or
or fun
.
The important points are:
Essentially the only way to use a function is to apply it to an
argument.19 Informal notation for applying a function
f to an argument a is to write f(a) or fa or even to show the
substitution of ``actual'' argument for the ``formal'' one as in sin(a) or
ea. We adopt an operator name to remind ourselves that
applicationapplication is a distinct operation. So we write
ap(f; a). But again, Nuprl can display this anyway the user pleases,
e.g. as f(a) or fa or even
or f@a.
One of the major discoveries from a systematic study of function notations, especially the lambda calculus and combinatory calculus and later programming languages, is that rules for formally calculating with functions can be given independently of their meaning, especially independently of types.
The rules for calculation or for ``definitional equality'' can be expressed
nicely as evaluation rules. Here is the so called
``call_by_name''call by name evaluation rule.definedness
(
)
The ``call_by_value''call by value rule is this
definedness (
)
Closed expression functions like
or
are called combinatorscombinator; these two
are ``polymorphic''polymorphic in that we can compute their values
regardless of the form of the input. Thus
and
,
and
.
Other functions like
or
can only be reduced to values on inputs of a
specific form, and others like
or
reduce to meaningful values (typed values) only on specific
inputs. For example,
but
is not a canonical value let alone a sensible value. In
the case
the result of
evaluation is the value
suc(pair(0; 0)), but this value has no
type.