I got inspired by Andrei's "Generic Programming Must Go" talk:
https://www.youtube.com/watch?v=mCrVYYlFTrA

I.e. writing functions with static if-s, based on what we know about the input.
So the question is how to annotate the input variables?

Adam showed an excellent solution for this, by wrapping the value into a struct, and using alias: http://stackoverflow.com/questions/31442059/virtual-static-value-types

Unfortunately, it's not without runtime penalty. I have checked this idea with ints, against the generated asm.dlang.org code. Unfortunately the struct wrapper results in longer asm code. In theory such run-time penalty is not necessary, as everything is available compile-time.

To understand my use-case, here is an example "math library" that skips certain validations or computations altogether, whether some properties of the input can be inferred from how the value was produced:

import std.math : sqrt;
import std.conv;

struct Positive {
        int num;
        alias num this;
}

Positive abs(T)(T n) {
        static if (is(T == Positive)) {
                return n;
        }
        if (n >= 0) return Positive(n);
        return Positive(-n);
}

Positive isqrt(T)(T x) {
        static if (is(T == Positive)) {
                return Positive(sqrt(x.to!float).to!int);
        }
        if (x<0) {
                throw new Exception("no root for negative numbers");
        }
        return Positive(sqrt(x.to!float).to!int);
}

unittest {
        assert(abs(-4) == 4); // full abs runs
assert(isqrt(4).abs() == 2); // full isqrt runs, abs returns n immediately. assert(abs(-4).isqrt() == 2); // full abs runs, isqrt return immediately, skipping validation;
}

Although this code is fully operational, presents nice api and compile-time optimizations, the extra Struct wrapper is not without runtime penalty.

Is there a solution that results the same static optimizations, but has no runtime penalty, i.e. the functions just operates with ints? (At least when compiled)

Thanks, Tamas

Reply via email to