Here's a basic implementation: import std.stdio; import std.traits; import std.metastrings;
template count(T...) { enum count = T.length; } template curry(alias fun, args...) { static if (args.length > (ParameterTypeTuple!fun).length) { static assert(0, Format!("Tried to pass %s arguments, max is %s.", count!args, (ParameterTypeTuple!fun).length)); } static if (is(typeof(fun) == delegate) || is(typeof(fun) == function)) { ReturnType!fun curry() { return fun(args); } } } void foo(int x, int y) { writeln(x, y); } alias curry!(foo, 1, 2) bar; void main() { bar(); } It will complain if you try to pass it more arguments than a function can take. I didn't implement curry's original else clause because I have no idea what's going on there (some comments would be useful in Phobos implementations, people!......) There is some wacky error if I didn't use the count template workaround. If I try to use args.length twice, like so: static if (args.length > (ParameterTypeTuple!fun).length) { static assert(0, Format!("Tried to pass %s arguments, max is %s.", args.length, (ParameterTypeTuple!fun).length)); } Then I get back: identifier 'length' of 'args.length' is not defined But it only errors out in the static assert, and yet it can check args.length in the static if. Really weird.