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.