Content deleted Content added
CortexFiend (talk | contribs) Link suggestions feature: 3 links added. |
|||
(73 intermediate revisions by 55 users not shown) | |||
Line 1:
{{Short description|Programming language implementation problem}}
The difficulty only arises if the body of a [[nested function]] refers directly (i.e., not
There are two subtly different versions of the funarg problem. The '''upwards funarg problem''' arises from returning (or otherwise transmitting "upwards") a function from a function call. The '''downwards funarg problem''' arises from passing a function as a parameter to another function call.
==Upwards funarg problem==
When one function calls another during a typical program's execution, the local state of the
One solution to the upwards funarg problem is to simply allocate all activation records from the [[
Some efficiency-minded compilers employ a hybrid approach in which the activation records for a function are allocated from the stack if the [[compiler]] is able to deduce, through [[static program analysis]], that the function creates no upwards funargs. Otherwise, the activation records are allocated from the heap.
Another solution is to simply copy the value of the variables into the closure at the time the closure is created. This will cause a different behavior in the case of mutable variables, because the state will no longer be shared between closures. But if it is known that the variables are constant, then this approach will be equivalent. The [[ML (programming language)|ML]] languages take this approach, since variables in those languages are bound to values—i.e. variables cannot be changed. [[Java_(programming_language)|Java]] also takes this approach with respect to anonymous classes (and lambdas since Java 8), in that it only allows one to refer to variables in the enclosing scope that are effectively <code>final</code> (i.e. constant).
===Example===▼
The following [[Haskell (programming language)|Haskell]]-inspired [[pseudocode]] defines [[function composition]]:▼
Some languages allow the programmer to explicitly choose between the two behaviors. [[PHP]] 5.3's anonymous functions require one to specify which variables to include in the closure using the <code>use ()</code> clause; if the variable is listed by reference, it includes a reference to the original variable; otherwise, it passes the value. In Apple's [[Blocks (C language extension)|Blocks]] anonymous functions, captured local variables are by default captured by value; if one wants to share the state between closures or between the closure and the outside scope, the variable must be declared with the <code>__block</code> modifier, in which case that variable is allocated on the heap.
compose f g = λx → f (g x)▼
▲===Example===
The <code>[[lambda|λ]]</code> is the operator for constructing a new function, in this case of one argument <code>''x''</code>, which returns the result of first applying <code>''g''</code> to <code>''x''</code>, then applying <code>''f''</code> to the result. This function carries the functions <code>''f''</code> and <code>''g''</code> (or pointers to them) as internal state.▼
▲The following [[Haskell (programming language)|Haskell]]-
▲
The problem in this case exists if the compose function
==Downwards funarg problem==
A downwards funarg may also refer to a function's state when that function is not actually executing. However, because, by definition, the existence of a downwards funarg is contained in the execution of the function that creates it, the
The downwards funarg problem complicates the efficient compilation of [[tail
==Practical implications==
Historically, the upwards funarg problem has proven to be
In [[functional language]]s, functions are first-class values
==See also==▼
* [[Closure (computer science)]]▼
* [[Functional programming]]▼
* [[Lambda calculus]]▼
* [[Man or boy test]]
* [[Name binding]]▼
* [[Referential transparency]]
* [[Scope (programming)]]▼
* [[Spaghetti stack]]▼
==References==
{{Reflist}}
▲==See also==
▲*[[Closure (computer science)]]
▲*[[Functional programming]]
▲*[[Lambda calculus]]
▲*[[Name binding]]
▲*[[Scope (programming)]]
▲*[[Spaghetti stack]]
==External links==
* [[Joseph Weizenbaum]]. [http://www.softwarepreservation.org/projects/LISP/MIT/Weizenbaum-FUNARG_Problem_Explained-1968.pdf "The FUNARG Problem Explained"], 1968.
* [[Joel Moses]]. [http://dspace.mit.edu/handle/1721.1/5854 "The Function of FUNCTION in LISP, or Why the FUNARG Problem Should be Called the Environment Problem"].
* [https://web.archive.org/web/20120722020445/http://classes.soe.ucsc.edu/cmps203/Winter11/09-lambda.ppt.pdf Bindings, Procedures, Functions, Functional Programming, and the Lambda Calculus]
[[Category:Compiler construction]]
▲*[[Joel Moses]]. The Function of FUNCTION in LISP, or Why the FUNARG Problem Should be Called the Environment Problem. [https://dspace.mit.edu/handle/1721.1/5854 MIT AI Memo 199], 1970.
[[Category:Programming language implementation]]
|