Lambda Calculus Part 2: Lexical Scope
We saw an example of a curried function in part 1:
Curried functions represent 1 two parameter function with 2 one parameter functions.
Although it may seem obvious, it is important to recall that a variable must always be declared. To declare a variable is, by definition, to bind it to some value. Let’s say a variable references an identifier that isn’t bound to any value.
Without running this code, you should be able to readily predict what it will return (or, rather, that it won’t return any value whatsoever). If you were to run this code in a REPL, you’d get
So, let’s break down our add function to illustrate how closure works. After all,
add really contains two functions; let’s look at the inner function first. On its own, this inner function
y => x + y;
will obviously result in an error; x is a free variable. What happens when you surround that inner function with the outer function to get
let add = x => y => x + y;? This is exactly where closure comes in. The
Let’s return to lambda calculus notation for a moment, and look at two more expressions to determine if they have any free variables.
This expression contains two free variables:
x is a parameter in the enclosing λ expression. Let’s try another:
This should be intuitive by now: all variables are bound.
It is important to emphasize that a lambda expression is only valid if all variables are bound.
The next steps in the lambda calculus will be to look at two rules for evaluating lambda expressions: α conversion and β reduction. Understanding these evaluation rules will allow us to show the potential of the lambda calculus to build up and express very complex abstractions from extremely simple building blocks.