Operator overloading or alternatives to expression templates

H. S. Teoh via Digitalmars-d digitalmars-d at puremagic.com
Fri Sep 11 17:03:58 PDT 2015


On Fri, Sep 11, 2015 at 07:47:42PM -0400, Andrei Alexandrescu via Digitalmars-d wrote:
> On 09/11/2015 03:40 PM, Martin Nowak wrote:
> >I find the reasons for turining down my ER a bit moot.
> >
> >[Issue 14593 – operator overloading can't be used with expression
> >templates](https://issues.dlang.org/show_bug.cgi?id=14593)
> >
> >AFAIK expression templates are the primary choice tom implement SIMD
> >and matrix libraries.
> >And I still have [this idea](http://dpaste.dzfl.pl/cd375ac594cf) of
> >implementing a nice query language for ORMs.
> 
> Expression templates are interesting, but from experience with them in
> C++ they're more trouble than they're worth. They haven't made much
> inroads in C++ outside exotic libraries because (a) they have odd and
> random limitations and corner cases and (b) they have really byzantine
> failure modes. Just look at any non-toy-example C++ use of ETs - it's
> completely bizarre.

A number of years ago I wrote a computational application using Blitz++,
an ET-based matrix / multidimensional array C++ library, and I have to
say that the experience was mostly pleasant.  However, it did push the
limits of operator overloading abuse, such as:

	Array<2,int> matrix = Array<2,int>(4, 4);
	matrix = 1, 0, 0, 0,
	         0, 1, 0, 0,
		 0, 0, 1, 0,
		 0, 0, 0, 1;

It also had unexpected reference/copying semantics (operator=() copies
by reference, but `=` in a variable declarationi copies by value), as
well as the occasional wrinkle when assigning the result of an
expression template to a variable (sometimes you have to explicitly call
a function to turn it into something storable in a variable).

The error messages however, were completely inscrutable, just as you
said. They generally begin anywhere from 15-16 lines of compiler output
per error, and only grows from there. Needless to say, I did not have
the patience (nor persistence!) to decipher those error messages; most
of my efforts lay in copying textbook examples from the documentation
and modifying them piece by piece, checking their compilability at every
step, until they matched what I ultimately wanted. Writing anything
complex directly was an invitation to be faced with an incomprehensible
screen-filling error message (often more than one), and endless hours of
randomly modifying random bits of syntax in hopes that the error will
somehow, magically, go away.


> I'd say if a language wants to support expression templates properly,
> there's a lot of careful design to get into it, way beyond
> intercepting operators. Like e.g. C#/LINQ. I don't think D is prepared
> for that.

Pluggable syntax modules seem like an attractive idea, though. But
probably outside the scope of D2 at present.


[...]
> >Does anyone have a different idea how to make a nice query language?
> >db.get!Person.where!(p => p.age > 21 && p.name == "Peter")
> 
> There's two canonical ways to do that.
> 
> 1. Use lambdas, which seem to already do what you want:
> 
> db.get!Person.filter!(p => p.age > 21 && p.name == "Peter")
> 
> The way this'd go, the db.get!Person() call returns an input range of
> Person. Presumably introspection is being used to bind fields in the
> query such as "age" and "name" to static field names in struct Person.
> Then good old std.algorithm.filter takes care of the rest.
> 
> 2. If you want to embed real SQL into D, use string-based DSLs.
[...]

Yeah, string-based DSLs make more sense in D: avoid complicating the
core language, thorny issues surrounding operator overloading (and the
abuse thereof), and also allow fully-free syntax of your choice.  With
CTFE, you can parse just about any DSL with any syntax at compile-time,
thus incur none of the performance issues that runtime string-based DSLs
would have.


T

-- 
The only difference between male factor and malefactor is just a little emptiness inside.


More information about the Digitalmars-d mailing list