Closures in Cilk

Here’s the translated code and explanation in Markdown format suitable for Hugo:

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

#include <stdio.h>

// 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.
int* intSeq() {
    static int i = 0;
    return &i;
}

int main() {
    // We call intSeq, assigning the result (a pointer to an integer)
    // to nextInt. This pointer captures the address of the static
    // variable i, which will be updated each time we dereference
    // and increment nextInt.
    int* nextInt = intSeq();

    // See the effect of the closure by dereferencing and
    // incrementing nextInt a few times.
    printf("%d\n", ++(*nextInt));
    printf("%d\n", ++(*nextInt));
    printf("%d\n", ++(*nextInt));

    // To confirm that the state is unique to that
    // particular function, create and test a new one.
    int* newInts = intSeq();
    printf("%d\n", ++(*newInts));
}

When you run this program, you’ll see the following output:

1
2
3
1

In Cilk, we don’t have direct support for closures as in some other languages. However, we can achieve similar functionality using static variables and pointers. In this example, we use a static variable i inside the intSeq function to maintain state between calls.

The intSeq function returns a pointer to this static variable. Each time we call intSeq, we get a pointer to the same static variable. By dereferencing and incrementing this pointer, we can simulate the behavior of a closure.

The last feature of functions we’ll look at for now is recursion, which Cilk fully supports.