In
programming languages
A programming language is a system of notation for writing computer programs.
Programming languages are described in terms of their syntax (form) and semantics (meaning), usually defined by a formal language. Languages usually provide features ...
, defunctionalization is a
compile-time
In computer science, compile time (or compile-time) describes the time window during which a language's statements are converted into binary instructions for the processor to execute. The term is used as an adjective to describe concepts relat ...
transformation which eliminates
higher-order function In mathematics and computer science, a higher-order function (HOF) is a function that does at least one of the following:
* takes one or more functions as arguments (i.e. a procedural parameter, which is a parameter of a procedure that is itself ...
s, replacing them by a single first-order ''apply'' function. The technique was first described by
John C. Reynolds
John Charles Reynolds (June 1, 1935 – April 28, 2013) was an American computer scientist.
Education and affiliations
John Reynolds studied at Purdue University and then earned a Doctor of Philosophy (Ph.D.) in theoretical physics from Harvard U ...
in his 1972 paper, "Definitional Interpreters for Higher-Order Programming Languages". Reynolds' observation was that a given program contains only finitely many function abstractions, so that each can be assigned and replaced by a unique identifier. Every function application within the program is then replaced by a call to the ''apply'' function with the function identifier as the first argument. The ''apply'' function's only job is to dispatch on this first argument, and then perform the instructions denoted by the function identifier on the remaining arguments.
One complication to this basic idea is that
function abstractions may reference
free variables
In mathematics, and in other disciplines involving formal languages, including mathematical logic and computer science, a variable may be said to be either free or bound. Some older books use the terms real variable and apparent variable for f ...
. In such situations, defunctionalization must be preceded by
closure conversion (lambda lifting), so that any free variables of a function abstraction are passed as extra arguments to ''apply''. In addition, if
closures are supported as
first-class values, it becomes necessary to represent these captured bindings by creating data structures.
Instead of having a single ''apply'' function dispatch on all function abstractions in a program, various kinds of
control flow analysis
In computer science, control-flow analysis (CFA) is a static-code-analysis technique for determining the control flow of a program. The control flow is expressed as a control-flow graph (CFG). For both functional programming languages and objec ...
(including simple distinctions based on
arity
In logic, mathematics, and computer science, arity () is the number of arguments or operands taken by a function, operation or relation. In mathematics, arity may also be called rank, but this word can have many other meanings. In logic and ...
or
type signature
In computer science, a type signature or type annotation defines the inputs and outputs of a function, subroutine or method. A type signature includes the number, types, and order of the function's arguments. One important use of a type sign ...
) can be employed to determine which function(s) may be called at each function application site, and a specialized ''apply'' function may be referenced instead. Alternatively, the target language may support indirect calls through
function pointer
A function pointer, also called a subroutine pointer or procedure pointer, is a pointer referencing executable code, rather than data. Dereferencing the function pointer yields the referenced function, which can be invoked and passed arguments ...
s, which may be more efficient and extensible than a dispatch-based approach.
Besides its use as a compilation technique for higher-order
functional languages
In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions that map ...
, defunctionalization has been studied (particularly by
Olivier Danvy and collaborators) as a way of mechanically transforming
interpreters
Interpreting is translation from a spoken or signed language into another language, usually in real time to facilitate live communication. It is distinguished from the translation of a written text, which can be more deliberative and make use o ...
into
abstract machine
In computer science, an abstract machine is a theoretical model that allows for a detailed and precise analysis of how a computer system functions. It is similar to a mathematical function in that it receives inputs and produces outputs based on p ...
s. Defunctionalization is also related to the technique from
object-oriented programming
Object-oriented programming (OOP) is a programming paradigm based on the concept of '' objects''. Objects can contain data (called fields, attributes or properties) and have actions they can perform (called procedures or methods and impl ...
of representing functions by
function object
In computer programming, a function object is a construct allowing an object (computer science), object to be invoked or called as if it were an ordinary subroutine, function, usually with the same syntax (a function parameter that can also be a ...
s (as an alternative to closures).
Example
This is an example given by
Olivier Danvy, translated to Haskell:
Given the Tree datatype:
data Tree a = Leaf a
, Node (Tree a) (Tree a)
We will defunctionalize the following program:
cons :: a -> -> cons x xs = x : xs
o :: (b -> c) -> (a -> b) -> a -> c
o f g x = f (g x)
flatten :: Tree t -> flatten t = walk t []
walk :: Tree t -> [t] -> walk (Leaf x) = cons x
walk (Node t1 t2) = o (walk t1) (walk t2)
We defunctionalize by replacing all higher-order functions (in this case,
o
is the only higher-order function) with a value of the
Lam
datatype, and instead of calling them directly, we introduce an
apply
function that interprets the datatype:
data Lam a = LamCons a
, LamO (Lam a) (Lam a)
apply :: Lam a -> -> apply (LamCons x) xs = x : xs
apply (LamO f1 f2) xs = apply f1 (apply f2 xs)
cons_def :: a -> Lam a
cons_def x = LamCons x
o_def :: Lam a -> Lam a -> Lam a
o_def f1 f2 = LamO f1 f2
flatten_def :: Tree t -> flatten_def t = apply (walk_def t) []
walk_def :: Tree t -> Lam t
walk_def (Leaf x) = cons_def x
walk_def (Node t1 t2) = o_def (walk_def t1) (walk_def t2)
See also
* Closure conversion
*
Partial evaluation
In computing, partial evaluation is a technique for several different types of program optimization by specialization. The most straightforward application is to produce new programs that run faster than the originals while being guaranteed to ...
References
*
* (More comprehensive version
Technical Report BRICS-RS-01-23
* {{cite journal
, first1 = Olivier , last1 = Danvy , author-link1 = Olivier Danvy
, first2 = Kevin R. , last2 = Millikin
, title = Refunctionalization at Work
, journal = Science of Computer Programming
, volume = 74 , date=June 2009
, pages = 534–549
, number = 8
, doi=10.1016/j.scico.2007.10.007
, doi-access =
(Also available a
Technical Report BRICS-RS-07-7
External links
Defunctionalization (Programming Languages) Oxford University.
Implementation of functional programming languages