I am writing a domain specific language of sorts in D for the
lambda calculus. One of my requirements is that I should be able
to generate expressions like this:
new Abstraction(v1, M)
like this:
L!(x => M)
It is common to want to write things like
L!(x => L!(y => M))
but it is much nicer to write that like
L!((x, y) => M)
So, I have created a templated function for this.
Abstraction L(alias f)() {
static if(__traits(compiles, f(null))) {
auto v1 = new Variable;
return new Abstraction(v1, f(v1));
} else static if(__traits(compiles, f(null, null))) {
auto v1 = new Variable;
auto v2 = new Variable;
return new Abstraction(v1, new Abstraction(v2, f(v1,
v2)));
} else static if(__traits(compiles, f(null, null, null))) {
auto v1 = new Variable;
auto v2 = new Variable;
auto v3 = new Variable;
return new Abstraction(v1, new Abstraction(v2, new
Abstraction(v3, f(v1, v2, v3))));
}
}
This only works for at most 3 parameter delegates. If I want to
add more, I have to linearly add more static ifs in the obvious
way. However, I believe I can make this function scalable using
string mixins and other magic. Any insight into this is much
appreciated.