# From the lambda calculus to real programming languages

The Lambda Calculus is the basis of the functional languages. These usually have a "core" corresponding to the Lambda Calculus, plus:
• Some data structures and primitives: for convenience of programming.
• Declarations: for convenience of programming.
• Types (not always).
• A fixed evaluation strategy.

## Order of evaluation

In Lambda Calculus every reducible subterm (beta redex) can be selected for reduction. This gives rise to nondeterminism. In real languages, on the contrary, the choice is fixed.
• Note that the choice comes from the congruence rules relative to application. When we have a term (\x.M) N, we can choose to evaluate N first, or to make the beta-reduction first. There are two main strategies, depending on this choice:

• Call-by-value, or eager strategy, which always evaluates the argument N first, and
• Call-by-name, or lazy strategy, which first makes the substitution (beta-reduction), and evaluates the arguments N only if necessary (i.e. if it is necessary for the evaluation of M[N/x]).
It can be shown that the lazy strategy is complete, i.e. it covers all the possible reductions of the Lambda Calculus, while the eager strategy is not complete. On the other hand, the eager strategy is (usually) more efficient, although not always. In fact, if x occurs several times in M, then in call-by-value we evaluate N only once, while in call-by-value (in principle) we would evaluate N several times. However, there are implementations which use a pointer to N, instead of N itself; in these implementations N will be evaluated at most once, and the performance is better. (The use of pointers however is rather tricky with higher-order.)

Other issues of relevance here are:

• Evaluation under lambda abstraction: in real programming languages such evaluation is not done. A function is never reduced, even if its body could be simplified.

• Existence of special forms: real languages have constructs that do not follow the general rules of application, and are specified by ad-hoc rules. Example: the if-then-else construct.

## Some programming languages based on the lambda calculus

Several languages have been proposed. For instance:
• Lisp (1958, Mc Carty). Untyped. Eager. Dynamic Scope (This was actually unintended, and it is considered a mistake, in fact the Lambda-Calculus has lexical scope. Dynamic scope corresponds to "capturing" free (i.e. global) variables when performing beta reduction.)
• Scheme (1975). Untyped. Eager.
• ML (Milner, 1974). Typed. Eager. A more efficient version (Standard ML), using garbage collection, was implemented in 1985.
• CLOS (1988). Eager. Integrates the Functional and the Object-Oriented paradigms.
• Haskell (1990). (Named after Curry!) Typed. Lazy.