Weak normal forms, call-by-name and call-by-value.

Normal order reduction will perform reductions both inside and outside abstractions. If we wish to regard reduction as a model of computation then only reductions outside of abstractions can be regarded as corresponding to running a program. Reductions inside a -abstraction are in effect manipulating program, something that is usually done by a compiler. Thus we introduce the ideas of weak normal order reduction and weak normal form in which the only reductions performed are performed outside of any -abstraction. This is also called call by name, and is safe in the sense that if a weak normal form exists, weak normal order reduction will find it.

Recall that normal order reduction takes the leftmost outermost redex. An alternative strategy is to take the leftmost innermost redex. This is call by value and is unsafe in the sense that an infinite sequence of reductions may arise despite the fact that a (weak) normal form exists.

Nevertheless most languages use some kind of call by value for almost all reductions because it is easier to implement efficiently than call by name (call by reference does not really make sense from the functional point of view).

Strictness and Laziness

A function is said to be strict if it is certain to need the value of its argument. The sin function for example is strict. The conditional function if is non-strict, since evaluating the expression if E1 E2 E3 can be performed without evaluating both E2 and E3. Indeed it would be impossible to write recursive functions without some laziness around.

Semantics

Our -calculus is a fine edifice, but is it sound? A mathematician looking at it for the first time would be reminded of a sad little story of the beginning of the 20th century: the mathematician Frege had built an elegant theory of sets; Unfortunately it was inconsistent - that is to say it had no meaning, and was torpedoed and sunk by Bertrand Russell. The problem with this set theory was that it allowed expressions of the form x\in x, and in particular allowed the formalism {x|x x} - `the set of all sets which are not members of themselves'. Consider {x|x x}\in{x|x x}. To give a meaning to this, we must assign the value TRUE or the value FALSE to it. But in either case we have a contradiction. There is a horrid formal resemblance to x.xx, and to x.xx x.xx which is allowed in the -calculus, and a nasty suspicion must arise in the mathematical mind that it might not be possible to give a `sensible' meaning to the -calculus in which the common-sense view of - expressions as functions can be substantiated.

Mending logic: Types and ZF-Set Theory

Fortunately for mathematics, set-theory was mended, and in two ways:

Russell and Whitehead's approach would require us to have a typed -calculus. Such a edifice can be built, and is indeed a very desirable mansion that actual programming languages may inhabit. However that elegant creature the Y combinator cannot dwell therein.

But it is not mathematically necessary to have a typed -calculus: it was shown in 1969 by Scott and Strachey that it is possible to devise an interpretation of the untyped -calculus in ZF set theory. Answer:

  • a countably infinite alphabet of variables, u... z, u1 ... z1, ... un ... zn, ... (It is of course only for human convenience that we allow distinct letters of the alphabet, formally and computationally we could use one sequence v1...)

    The -calculus with Constants, Primitives

    To make the -calculus suitable as a basis for practical computation we need to introduce entities which correspond to the capabilities of a real computer on which a program will run.

    A minimal capability would be provided by

    with the property that (if true E1E2) evaluates to E1, and (if false E1E2) evaluates to E2, and

    When are two expressions in -calculus `equal'?

    In secondary school we learned that expressions can be ``worked out'' or evaluated, by substitution and arithmetic. Thus x+2, with x=4, evaluates to 6. - and - reduction play the `working out' role for -calculus. However we also learned ways of determining that two expressions were identically equal. Thus x+2 and 2+x are identically equal in school algebra. In this section we want to examine the question `can we say whether two expressions in the -calculus are equal?'.

    calculus expressions denote functions

    In school algebra the symbols stand for numbers. In the -calculus they stand for, or as we say denote, functions (and other entities as well if we have added constants to make our -calculus impure). It turns out to be non-trivial to develop a theory of denotation for the -calculus - it took mathematicians nearly 30 years to come up with a satisfactory one, which we will not discuss here. However we will use some informal ideas of denotation in our discussion.

    For example we may say that x. + x 3 denotes the function `add 3', which is commonly regarded formally as the infinite set {... (-4,-1), (-3,0), (-2,1),(-1,2),(0,3),(1,4)...} of pairs of integers - you might think of it as a graph drawn on an infinite piece of graph paper.

    Thus we will discuss, informally, some rules that allow us to say that two expressions in the -calculus always denote the same thing.

    We can't always decide equality

    The -calculus is a powerful formalism, capable of expressing any computation. We know we can't decide whether two programs perform the same computation, so we should not expect to be able to decide whether two -calculus expressions are equal - we may be able to say `yes for sure', `no for sure', or `I can't tell'.

    -conversion and equality

    The -reduction rule that we have already met can also be used as a equality inference rule - in both directions.