Closures in D Programming Language

import std.stdio;

// This function intSeq returns another function, which
// we define anonymously in the body of intSeq. The
// returned function closes over the variable i to
// form a closure.
auto intSeq()
{
    int i = 0;
    return {
        i++;
        return i;
    };
}

void main()
{
    // We call intSeq, assigning the result (a function)
    // to nextInt. This function value captures its
    // own i value, which will be updated each time
    // we call nextInt.
    auto nextInt = intSeq();

    // See the effect of the closure by calling nextInt
    // a few times.
    writeln(nextInt());
    writeln(nextInt());
    writeln(nextInt());

    // To confirm that the state is unique to that
    // particular function, create and test a new one.
    auto newInts = intSeq();
    writeln(newInts());
}

D supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.

In this example, we define a function intSeq that returns another function. The returned function is defined anonymously within intSeq and closes over the variable i, forming a closure.

In the main function, we call intSeq and assign the result (a function) to nextInt. This function value captures its own i value, which will be updated each time we call nextInt.

We then demonstrate the effect of the closure by calling nextInt multiple times, showing how the internal state is maintained between calls.

Finally, we create a new closure by calling intSeq again and assigning it to newInts. This demonstrates that each closure has its own independent state.

To run the program:

$ dmd -run closures.d
1
2
3
1

The last feature of functions we’ll look at for now is recursion.