proxies

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sun Jan 25 08:29:24 PST 2009


Proxying is a useful technique for achieving nice effects like e.g. 
expression templates. Consider, for example, a matrix operators package 
that returns "lazy" matrices in the form of expression templates:

struct Matrix
{
     LazyMatrix!("a + b") opAdd(ref Matrix another) { ... }
     ...
}

Now if Matrix also defines construction and assignment from LazyMatrix, 
it's all fine and dandy because we can write:

Matrix a, b;
Matrix c = a + b; // no temporary matrix created!
a = b + c;        // no temporary matrix created!

The problem is that auto works against all this:

Matrix a, b;
auto c = a + b; // c is _not_ a Matrix!

Using c directly has any number of unpleasant surprises in store for the 
unwitting user. For example, modifying a and b also modifies c. And 
since c does the addition on the fly, using c[i, j] directly will 
actually be slower than using a matrix!

How could this effect be avoided? In the past I suggested that proxy 
objects should be private and offer opImplicitCast to the desired types. 
Then the compiler figures that out and generates code appropriately.

Another solution would be to define opAuto that dictates what happens 
when an automatic object is instantiated from the proxy type:

struct LazyMatrix(alias expression)
{
     Matrix opAuto() { ... }
}

Then writing:

auto c = a + b;

will automatically make c a Matrix and initialize it as prescribed by 
opAuto. On the other hand, if the type is explicitly requested, the 
proxy stays in vigor:

LazyMatrix!("a + b") cproxy = a + b;

This is, of course, useful when code is interested in capturing the 
proxy itself.

One problem I see with this is template instantiation:

void f(T)() { ... }
f(a + b);

What should T be? LazyMatrix or Matrix? Another problem is, what does 
typeof do?

typeof(a + b) c = a + b;

Should that be same as auto, or should typeof tell the truth? Any way 
you choose, some of the current assumptions will break. So I'm hoping 
someone here will come with a better idea.


Andrei



More information about the Digitalmars-d mailing list