title: Expression Templates in D
body: <p>The goal is to achieve the same effect as in <a href="http://en.wikipedia.org/wiki/Expression_templates" rel="nofollow">this C++ example</a>: avoid creating temporaries.  I've tried translating the C++ example to D without success.  I've also tried different approaches.</p>
  
  <pre><code>import std.datetime : benchmark;
  import std.stdio    : writefln, writeln;
  
  void bench(alias fun, string time = "msecs")(string msg, uint n = 1_000_000) {
    auto b = benchmark!fun(n);
    writefln(" %s: %s ms", msg, b[0].to!(time, int));
  }
  
  alias double Real;
  
  struct Expression(string op, E1, E2) {
    E1 _v1;
    E2 _v2;
    alias _v1 v1;
    alias _v2 v2;
  
    auto opIndex(size_t i) {
      return mixin("v1[i]" ~ op ~ "v2[i]");
    }
  
    auto opBinary(string op, E)(auto ref E e) {
      return Expression!(op, typeof(this), E)(this, e);
    }
  }
  
  struct ExpVector {
  
    Real[40] _data = void;
    alias _data this;
  
    this(Real datum) pure nothrow { _data = datum; }
  
    auto opBinary(string op, T)(auto ref T other) {
      return Expression!(op, typeof(this), T)(this, other);
    }
  
    void opAssign(E)(auto ref E exp) {
      foreach(i, ref datum; _data)
        datum = exp[i];
    }
  }
  
  struct Vector {
  
    Real[40] _data = void;
    alias _data this;
  
    this(Real datum) pure nothrow { _data = datum; }
  
    auto opBinary(string op)(auto ref Vector other) {
      Vector ret;
      foreach(i, datum; _data)
        ret[i] = mixin("datum" ~ op ~ "other[i]");
      return ret;
    }
  }
  
  void main() {
  
    ExpVector e1 = ExpVector(1.5);
    ExpVector e2 = ExpVector(7.3);
    ExpVector ef;
    void T1() {
      ef = (e1 + e2) * (e1 + e2);
    }
    bench!T1(" vector operations using template expression");
  
    Vector v1 = Vector(1.5);
    Vector v2 = Vector(7.3);
    Vector vf;
    void T2() {
      vf = (v1 + v2) * (v1 + v2);
    }
    bench!T2(" regular vector operations");
  
    void T3() {
      for(int i = 0; i &lt; vf.length; ++i)
        vf[i] = (v1[i] + v2[i]) * (v1[i] + v2[i]);
    }
    bench!T3(" what is expected if template expressions worked and temporaries were not created.");
  }
  </code></pre>
  
  <p>The expression template version is slower than the non-expression template version.  I was expecting the expression template version to be much faster and close to what is expected.  So what is wrong with my expression templates?  What's the correct way to do expression template in D?</p>