Lexical Closures for C++

We describe an extension of the C++ programming language that allows the nesting of function definitions and provides lexical closures with dynamic lifetime. Our primary motivation for this extension is that it allows the programmer to define iterators for collection classes simply as member functions. Such iterators take function pointers or closures as arguments; providing lexical closures lets one express state (e.g. accumulators) naturally and easily. This technique is commonplace in programming languages like Scheme, T, or Smalltalk-80, and is probably the most concise and natural way to provide generic iteration constructs in object oriented programming languages. The ability to nest function definitions also encourages a modular programming style. We would like to extend the C++ language in this way without introducing new data types for closures and without affecting the efficiency of programs that do not use the feature. In order to achieve this, we propose that when a closure is created, a short segment of code is generated that loads the static chain pointer and jumps to the body of the function. A closure is a pointer to this short segment of code. This trick allows us to treat a closure the same way as a pointer to an ordinary C++ function that does not reference any non-local, non-global variables. We discuss issues of consistency with existing scoping rules, syntax, allocation strategies, portability, and efficiency. 1 What we would like to add... and why We would like to be able to nest function definitions in C++ programs. In this section, we will discuss a number of reasons why the ability to nest function definitions is desirable. Almost all other modern programming languages such as Scheme, T, Smalltalk-80, Common Lisp, Pascal, Modula-2, and Ada offer this feature. To illustrate the utility of this language feature, we have to agree on syntax. To indicate that a function is defined inside another function, we will simply move its definition inside that function but otherwise write it the same way we would at global level. For example, the following fragment of code defines function2(int) inside function1(int): function1(int x) { // ... function2(int y) { // ... } // ... } ∗Author’s address: MIT Artificial Intelligence Laboratory, Room 711, 545 Technology Square, Cambridge, MA 02139, USA. The author was supported by a fellowship from the Fairchild foundation.