Closures in C and Scala

Deutsch

Are closures at all possible in C, without falling back to writing some interpreter in C and using that interpreted langauge?

Function pointers alone are far less than what is needed for closures. But they are one of the building blocks. It is quite hard to get the signature right, but a typedef proves to be useful.

The next issue is that C does not allow inner functions by default and that it is not possible to automatically include a context, which is essential for the concept of closures.

But it is surprisingly easy to overcome that issue:

The function is defined before the function within which it should be meant to be defined. It has an additional parameter for some „context“-struct, which can be used to include variables from that context.

struct closure;
typedef int (*fun_type)(const struct closure *context, const int param);

This struct includes the variables and a function pointer:

struct closure {
int x;
fun_type fun;
};

Now the function definition in languages that support closures still have to be provided in some way and this is done anonymously with some mechanism called lambda or so, within another function or method whose variables are implicitely included. In a way methods can be considered a special case of this, since they include access to attributes of the enclosing object. In C all functions are defined in the regular way, but this time the fun_type signature needs to be observed. References to enclosed variables need to be bound by explicitely putting them into the context:

int f(const struct closure *context, const int param) {
return (context->x) + param;
}

The second order function that returns the closure can now be defined. We only have to accept the C notation, but it is fully equivalent to closures, just a little bit more noise:

struct closure *adder(int x) {
struct closure *result = malloc(sizeof(struct closure));
result->x = x;
result->fun = f;
return result;
}

Off course memory management is always an issue to observe in C…

Now the whole thing can be used like this:

int main(int argc, char *argv[]) {
int retcode;
if (argc < 2) { usage(argv[0], "not enough parameters"); } int x = atoi(argv[1]); int y = atoi(argv[2]); struct closure *cl = adder(x); int i; for (i = 0; i < y; i++) { printf("cl(%d)=%d\n", i, cl->fun(cl, i));
}
}

The complete example can be found on github.

Off course the same is much shorter and more elegant in Scala:

object Closure {
def main(args : Array[String]) : Unit = {
val x : Int = args(0).toInt
val y : Int = args(1).toInt
val f : ((Int) => Int) = adder(x);
val arr = (1 to y).map(f)
println(arr.toString)
}

def adder(x : Int) : ((Int) => Int) = {
(y => x+y)
}
}

Even this can be found on
github.

Share Button

4 Gedanken zu „Closures in C and Scala

  1. Pingback: Closures in C | Karl Brodowskys IT-Blog

  2. Pingback: Find the next entry in a sequence | Karl Brodowsky's IT-Blog

    • That is an interesting aspect.
      I have actually avoided them, due to the fact that they are compiler specific. But it is interesting and I might take a look and write about them in the future.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.


*