Currying in C
Currying is not part of the C language. A few alternatives are shown that
can be used: Global variables, GCC extensions, code duplication, void
pointers, variable argument lists, and general parameter structs. Also
C++03 and C++11 examples are given.
At some occasions it might be necessary to mask certain function parameters. Say you have a numerical integration routine like the following:
double integrate(double (*f)(double), const double lower, const double upper, const double step);
This certainly is a reasonable thing to implement. As long as you have
functions with a single parameter, that is taking a single double
parameter,
this is just fine. One quickly encounters function that take multiple
arguments:
double func_2d(const double x, const double t);
Here x
is the variable that should be integrated over, t
is a parameter
that is supposed to be fixed during the integration.
The problem that you will then have is that you cannot put func_2d
into the
integrate
function. You will get errors about wrong signatures. Also the
integration routine must know which t
to choose.
There are a couple ways to solve this problem in plain C.
Global variable
One method is to just make t
a global variable. The function func_2d
would
then only have the parameter double x
and could be passed to integrate
. A
sample usage could then look like this:
double t; int main() { t = 17; const double integral = integrate(func_2d, 0, 1, 1e5); }
This does work. However, it has a couple major drawbacks:
 Encapsulation is broken. Therefore you cannot test the
func_2d
function on its own. Whatever test case you write will have to control the environment as well.  Thread safety is gone. As long as you use pure functions without any side
effects it is perfectly safe to use them in parallel. By creating a
dependency on a global variable, you cannot use
func_2d
in two concurrent threads any more. This might be remedied by using threadlocal variables.
Either way you will have a hard time debugging your program.
GCC extention
What you really need here is a closure, that is a function with some state attached to it. In Python, you can indeed do the following:
def func_2d(x, t): # ... def integrate(f, lower, upper, step): # ... def main(): t = 17 def wrapper(x): return func_2d(x, t) integral = integrate(wrapper, 0, 1, 1e15)
Notice how the wrapper
only takes the argument x
and takes t
from the
enclosing scope, the scope of main
. The exact same thing, the definition of a
function in a function, is also possible in JavaScript. It will create a
closure for you and basically copy the t
into wrapper
. This works in Python
as a function is more than just a function, it is a callable object, a
functor.
It would be really nice to do this in C as well. Unfortunately, C is too limited to allow for this construction. There is a GCC extension that you can use. With that, you can just write the following:
int main() { double t = 17; double wrapper(const double x) { return func_2d(x, t); } const double integral = integrate(wrapper, 0, 1, 1e5); }
This will work, but on GCC only. You must decide yourself whether using
nonstandard features is something that you want in your project. This will
work just fine on Linux. If you use Windows, you can install GCC via MingW or
Cygwin. This also works. On a Mac, you have bad luck, there is only Clang/LLVM.
There is a gcc
command on Mac OS, but it is just a symlink to clang
.
Multiple integration routines
One portable way to go about this is to define a couple more integration routines:
double integrate_0(double (*f)(double), const double lower, const double upper, const double step); double integrate_1(double (*f)(double, double), const double lower, const double upper, const double step, const double param_1); double integrate_2(double (*f)(double, double, double), const double lower, const double upper, const double step, const double param_1, const double param_2); // ...
This way, the additional parameters can be just fed through. For the func_2d
case one would use it like this:
int main() { const double integral = integrate_1(func_2d, 0, 1, 1e5, 17); }
On the first glance, this solution avoids all the trouble that the previous versions had. We can use that in threads, have no global variable. Tests can be written and it works on every compiler. Whenever ones copypastes source code, it should raise a flag. When using abstractions properly, it should rarely be necessary to copypaste source code.
Also this only gets worse when you have more parameters, parameters have other
types than double
and so on. Additionally, this has to be done for all the
numerical routines that you want to write. I would not want to maintain that!
void
pointer
One really generic way to get is is using a void *
for all the additional
parameters. The integrate
function would then look like this:
double integrate(double (*f)(double, void *), void * params, double lower, double upper, double step);
In order to use it, we need to write a wrapper for func_2d
:
double wrapper(const double x, void * const params) { double *pt = (double *) params; double t = *pt; return func_2d(x, t); }
When using this, we would do the following:
int main() { double t = 17; const double integral = integrate(wrapper, &t, 0, 1, 1e5, 17); }
Using this approach, we can extend it to an arbitrary amount of parameters
using a pointer to a struct
. Declaring one type of container for each
parameter pack and a wrapper for every function, we would get this:
struct t_container { double t; }; double wrapper(const double x, void *const input) { const struct t_container *const params = (struct t_container * const)input; const double t = params>t; return func_2d(x, t); }
This also works on every compiler and you can test it. It is extensible and the same integration routine can be used for functions with an arbitrary amount of parameters with arbitrary type.
It has some other problems, though. The void *
and the casting disables the
type system. That can make for nasty bugs that you can only notice at runtime.
If you are unlucky, this section only occurs late in your code and will crash
the program when you are paying for computing time. The type system is in place
to catch those errors, so one should no go against it when possible.
Also one introduces one level of indirection. A common saying is that every problem in computer science can be solved with another layer of indirection. Except for too many indirections, that is a different problem. Here the indirection will prohibit inlining which can speed your code up drastically if the function to evaluate is cheap. The repeated indirection should be cached eventually. I would still like to avoid that, however.
Variable argument list
Then there are variable argument lists (varg). Those are used in functions like
printf
which use three dots (...
) in their definition. Those are not type
safe either (This is why one has to get the %lf
in scanf
correct!). So
instead of casting from void *
, one will have to use the va_
family of
functions.
I have never used that myself, so I cannot give a proper example. But the integration routine would then have the following declaration:
double integrate(double (*f)(double, ...), const double lower, const double upper, const double step, ...);
From that I think I know about this, I would conclude that it is not
necessarily better than the version with void *
.
See the answer by mfro for an example of this method.
General parameter struct
If you work in a specific domain and the parameters that you pass are always
just a few from a given set, one can use a struct
that just contains all the
possible parameters that you have. Say we only want to do spacial integrations
in up to four dimensions of functions that perhaps depend on parameters a
and
b
. Then we could do the following:
struct Parameters { double a, b; double t; double x, y, z; };
Then we define some density function that depends on 3D space and the parameter
a
. It does not depend on time t
and not on b
. That is the function that
we want to integrate:
double density(const double x, const double y, const double z, const double a) { // ... }
First we want to integrate over x
. We define a wrapper function that just
takes x
and those other parameters p
such that we can feed it into the
modified integrate_param
function:
double wrapper_x(const double x, Parameters p) { return density(x, p.y, p.z, p.a); }
This should demonstrate this method. We can compare it to the other methods. The positive features are:
 Threadsafe.
 Typesafe.
 Portable (does not rely on compiler extensions).
 No global variables.
 No code replication with slightly changed arguments.
The drawbacks here are rather mild:

The number of parameters used in the program has to be somewhat limited.
One could perhaps start to recycle the names as long as they have the same type. So if all the parameters are
double
and one commits on not changing the parameters in theParameters
structure, one can use the same variable in different contexts. One just has to be really careful to avoid confusion. 
Calling a function with a large
struct
of unused parameters will result in more copy operations onto the stack before calling the function. This will only become important when the function itself is cheap to evaluate.One way to get around this would be passing
const Parameters *const p
instead of justParameters p
as an argument. This will add a layer of indirection and remove the copy. If one usesconst
, the compiler will still have a fair chance of optimizing. 
Function signatures are now rather useless. Every function in the program just takes a parameter scope. One cannot see from the function signature which parameters the function actually uses.
The same problem occurs when using global variables. Here at least it is not a side effect, the dependencies are just in the opaque
struct
now. Unit tests and the like are not affected by this. That is good!
Integration along x
would then look like this:
int main() { Parameters p; p.a = 17; p.y = 0.3; p.z = 3.4; const double integral = integrate_param(wrapper_x, p, 1, 1, 1e15); }
One could even go further and incorporate the first parameter into the struct
as well and only pass that.
I would like to thank Bartosz Kostrzewa for making me aware of this approach!
C++11 lambda
You may know that I am not a big fan of C. I much prefer C++ over its more expressive syntax as well as the powerful and often costless abstractions. This is a case where C++11 can give you a closure in a single line:
int main() { double t = 17; auto wrapper = [t](const double x) { return func_2d(x, t) }; const double integral = integrate(wrapper, 0, 1, 1e5); }
We will have to modify the declaration of integrate
slightly for this:
#include <functional> double integrate(std::function<double(double)> f, const double lower, const double upper, const double step);
Another neat thing is that the syntax of function pointers is much nicer in
C++11 and this also captures functors. Here you do not have any problems with
type unsafety or threading. It just works. It also does not depend on the
compiler, as long as that supports C++11. The IBM compiler on Blue Gene/Q does
not support that, so you will have to use bgclang
there.
C++03 functor
If you are in the unlucky position to deal with a compiler which does not support C++11, like before GCC 4.8, you will have to write the functor yourself. There is no nice lambda syntax in C++03. So you would create something like this:
struct Wrapper { double t; Wrapper::Wrapper(const double t) t(t) {}; double operator()(const double x) { return func_2d(x, t); } }
Then create an instance of that wrapper and pass it to the integrate
function:
int main() { Wrapper wrapper(17); const double integral = integrate(wrapper, 0, 1, 1e5); }
It seems that the functional
header has been around in
C++03 already, so one can use the same integrate
function as with the C++11
example.
See also: