Revision as of 11:28, 17 July 2013 editThepigdog (talk | contribs)Extended confirmed users5,174 edits →Candidate Prefix Lambda for Lifting← Previous edit | Revision as of 11:30, 17 July 2013 edit undoThepigdog (talk | contribs)Extended confirmed users5,174 edits →ReferencesNext edit → | ||
Line 223: | Line 223: | ||
The Y-Combinator calls its paramter (function) repeatedly on itself. The value is defined if the function has a ]. But the function will never terminate. | The Y-Combinator calls its paramter (function) repeatedly on itself. The value is defined if the function has a ]. But the function will never terminate. | ||
== Lambda dropping in Lambda Calculus == | |||
== References == | == References == |
Revision as of 11:30, 17 July 2013
Lambda lifting or closure conversion is the process of eliminating free variables from local function definitions from a computer program. The elimination of free variables allows the compiler to hoist local definitions out of their surrounding contexts into a fixed set of top-level functions with an extra parameter replacing each local variable. By eliminating the need for run-time access-links, this may reduce the run-time cost of handling implicit scope. Many functional programming language implementations use lambda lifting during compilation.
The term "lambda lifting" was first introduced by Thomas Johnsson around 1982.
The reverse operation is called lambda dropping.
Algorithm
The following algorithm is one way to lambda-lift an arbitrary program in a language which doesn't support closures as first-class objects:
- Rename the functions so that each function has a unique name.
- Replace each free variable with an additional argument to the enclosing function, and pass that argument to every use of the function.
- Replace every local function definition that has no free variables with an identical global function.
- Repeat steps 2 and 3 until all free variables and local functions are eliminated.
If the language has closures as first-class objects that can be passed as arguments or returned from other functions (closures), the closure will need to be represented by a data structure that captures the bindings of the free variables.
Example
Consider the following OCaml program that computes the sum of the integers from 1 to 100:
let rec sum n = if n = 1 then 1 else let f x = n + x in f (sum (n - 1)) in sum 100
(The let rec
declares sum
as a function that may call itself.) The function f, which adds sum's argument to the sum of the numbers less than the argument, is a local function. Within the definition of f, n is a free variable. Start by converting the free variable to an argument:
let rec sum n = if n = 1 then 1 else let f w x = w + x in f n (sum (n - 1)) in sum 100
Next, lift f into a global function:
let rec f w x = w + x and sum n = if n = 1 then 1 else f n (sum (n - 1)) in sum 100
The following is the same example, this time written in JavaScript:
// Initial version function sum (n) { function f (x) { return n + x; } if (n == 1) { return 1; } else { return f( sum(n - 1) ); } } // After converting the free variable n to a formal parameter w function sum (n) { function f (w, x) { return w + x; } if (n == 1) { return 1; } else { return f( n, sum(n - 1) ); } } // After lifting function f into the global scope function f (w, x) { return w + x; } function sum (n) { if (n == 1) { return 1; } else { return f( n, sum(n - 1) ); } }
Lambda Lifting in Lambda calculus
This section describes lambda lifting in more detail, and describes the process when used in Lambda Calculus. Lambda lifting may be used to convert a program written in Lambda Calculus into a functional program, without lambdas. This demonstrates the equivalence of programs written in Lambda Calculus and programs written as functions.
Each Lambda Lift takes a sub expression of a lambda expression and replaces it by a function call (application) to a function that it creates. The process is similar to refactoring out some code and putting it in a function. Lambda Lifts may be repeated until the lambda expression is completely converted.
Rules for Lambda Lifting
This section describes how to lift and export one lambda expression to a function definition.
The lift is given a sub-expression (called S) to be lifted. For S;
- Create a name for the function that will replace S (called f). Make sure that the name identified by f has not been used.
- Add parameters to f, for all the free variables in S, to create an expression g (see make-call).
The lift is also given a "let" expression, A "let" expression is an expression used in functional languages to represent a number of conditions that are true in interpreting an expression. It is used here to represent conditions true on a lambda expression. For example,
where
- F is function definitions.
- L is a lambda expression.
The lambda-lift is implemented in the rule below.
The new lambda expression has S substituted for g. Note that L means substitution of S for g in L. The function definitions has the function definition g = S added.
The two rules below show how to construct a function call (or application) out of a function name f by adding parameters for each variable in the free variable set (represented by V),
The set of variables already used in is represented by,
The expression S will usually have leading lambdas. These may be moved to the other side of the equation as parameters using the rule;
Lamba-Lift transform of a lambda expression to functions
This section describes the process of performing a sequence of lifts to convert any lambda expression into an equivalent functional program.
Calling lambda-lift-tran on a lambda expression gives you a functional program in the form,
- let M in N
where M is a series of function definitions, and N is the expression representing the value returned.
The processing of transforming the lambda expression is a series of lifts. Each lift has,
- A sub expression chosen for it by candidate-prefix-lambda. The sub expression should be chosen so that it may be converted into an equation with no lambdas.
- The lift is performed by a call to lambda-lift as described in the previous section,
Candidate prefix lambda for lifting
The expression to be lifted must be chosen so that the equation created may be converted into an equation without lambdas using the rule,
The expression may have any number of lamdas prefixed at the start, but in the body of the expression, must have no lambda abstractions. This is achieved by looking for the deepest lambda prefix in the expression.
The rules are described below,
to be completed
Conversion between let and lambda expression
A let expression may be converted back into a lambda expression by repeated application of the following law,
The result has the lift restructure, but the restructure is within the Lambda Calculus.
Example
For example the Y combinator,
Lambda Expression | Function | From | To | Variables | |
---|---|---|---|---|---|
1 | true | ||||
2 | |||||
3 | |||||
4 | |||||
5 |
The first sub expression to be chosen for lifting is . This transforms the lambda expression into and creates the equation .
The second sub expression to be chosen for lifting is . This transforms the lambda expression into and creates the equation .
And the result is,
Execution
Apply function to,
So,
or
The Y-Combinator calls its paramter (function) repeatedly on itself. The value is defined if the function has a fixed point. But the function will never terminate.
Lambda dropping in Lambda Calculus
References
- Attention: This template ({{cite doi}}) is deprecated. To cite the publication identified by doi:10.1145/258994.259007, please use {{cite journal}} (if it was published in a bona fide academic journal, otherwise {{cite report}} with
|doi=10.1145/258994.259007
instead.
See also
External links
- Lambda Lifting: Transforming Programs to Recursive Equations
- Explanation on Stack Overflow, with a JavaScript example