What is a 'closure' ?

What is a 'closure' ?

How are closures in ArBB different than the closures in Python or Erlang?


2 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

closure is a first-class function object that has captured the state of free
variables (variables declared outside a function but referred to from inside
it, also known as non-local variables) in effect at the time and place it was
constructed. Closures are related to lambda expressions, except lambda
expressions are definitionsof an anonymous function, whereas a
closure is anactual objectrepresenting a specific instance
of a function bodycombined withthe captured environment.
The distinction is important when the same function definition can be
applied multiple times in different environments, that is, with different
values of free variables. In this case, distinct closure objects

represents closure objects as, well, ordinary C++ objects. You can
just call capture on a C++ function using ArBB types, and ArBB will compile
and return a closure object, which can in turn be used as a
function. When the closure is built, the current state of any
non-local C++ variables the original C++ function refers to will be frozen and
baked into the closure object.This is extraordinarily
useful for generic programming.
Basically, you can write a
single function parameterized any way you want with C++ variables (and control
flow, and data structures!). Then set the parameters to the values to
want and capture a closure. Then change the parameters and capture
another closure, for as many variants as you want. Each variant
will be compiled and optimized separately by ArBB. In other words,
ArBB supports function specialization under direct programmer control.

In pure functional languages with immutable variables, the
non-locals referenced by closures are also immutable and only the place
(scope) where the closure is created matters. In imperative
languages, free non-local variables may be mutable and so the time of capture
also matters, but in a useful way: you can update non-locals and create new,
different closures. ArBB closures (and C++ lambda expressions) also
support an additional extension to the concept: you can have both by-value and
by-reference non-locals. By-value non-locals are frozen at capture,
but by-reference variables can be updated even after capture and the closure
will use the new value. In ArBB, C++ non-locals are captured
by-value and ArBB non-locals are captured by-reference. Since you can use
value to access the current value of an ArBB type as a C++ type, you can use
this to freeze (convert to by-value) non-local ArBB variables too, if you want.

Purists would argue that allowing by-reference non-locals is a
misuse of the term closure, but such parameters are useful in imperative
languages, and it can also be argued that utility beats purity in this case.

in Python and Erlang are basically similar to ArBB closures, except ArBB
closures arealwaysdynamically compiled to take advantage of the
frozen values of the captured free variables. Also, in pure
functional Erlang (or any pure functional language), you wont have
by-reference non-locals, since mutation is not allowed in pure functional

An interesting discussion of the use (and misuse) of the term
closure can be found here, with examples from various languages:


Closures are also discussed at length in the ArBB User Guide and
API manual, so please look there for more information:

User Guide:http://software.intel.com/sites/products/documentation/arbb/arbb_userguide_win/index.htm
API Manual:http://software.intel.com/sites/products/documentation/arbb/arbb_manual_win/index.htm

User Guide:http://software.intel.com/sites/products/documentation/arbb/arbb_userguide_lnx/index.htm
API Manual:http://software.intel.com/sites/products/documentation/arbb/arbb_manual_lnx/index.htm

PS: The implementation of closures in ArBB does not require lambda
expressions in C++. They are related concepts, but the implementations
are totally separate. Machine language for an ArBB closure is
generated by ArBB. Machine language for a lambda expression is
generated by C++, and does not have the same scope for run-time specialization
and optimization as ArBB closures. In particular, C++ lambda
expressions do generate an object that can be thought of as a closure, but this
is just a pair consisting of a function and a data record storing captured
variables: the code is not recompiled to take advantage of the run-time state
of the captured free variables, which we can (and do!) in ArBB. Both
lambdas and ArBB closures can capture state, but only ArBB closures actually
generate and optimize code using that captured state.

Michael McCool, Principal Engineer
Software Services Group, Intel

Leave a Comment

Please sign in to add a comment. Not a member? Join today