This is from the office of not so useful things. If you try to fake dependent types in D you end instantiating many times the same template, inflating the binary with little purpose (because you are not very interested in the optimizations performed on the compile-time-known values). So to help that kind of coding I am thinking about something like this:


int foo1(@generic int c)(int x) if (c > 5) {
    return c * x * x; // foo body
}
void main() {
    auto r1 = foo1!(10)(15);
}



Its semantics is similar to this, but foo2() doesn't exists in the binary:


int foo2__(int c, int x) {
    return c * x * x; // foo body
}
int foo2(int c)(int x) if (c > 5) {
    return foo2__(c, x);
}
void main() {
    auto r1 = foo2!(10)(15);
}



So it's closer to this:


int foo3__(int c, int x) {
    return c * x * x; // foo body
}
void main() {
    enum int c = 10;
    static assert(c > 5, "required by foo");
    auto r1 = foo3__(c, 15);
}


So it looks like a function templated on some value, but you are instead calling a normal run-time function that requires the first arguments must be known at compile-time, and they get verified by template constraints.

So all this is just a way to perform compile-time tests on values, avoiding the instantiation of many useless templates. Those tests are one of the two halves of the tests of dependency of the types :-)

Bye,
bearophile

Reply via email to