opEquals/opCmp returning other types

Don Clugston dac at nospam.com
Wed Mar 21 04:05:41 PDT 2012


On 19/03/12 01:54, Brian Palmer wrote:
> I'm working on a DSL for generating SQL queries, based loosely on
> Python's SQLAlchemy and Ruby's Sequel. One nice thing about the DSL is
> the compact syntax for specifying WHERE clauses. With some fiddling, I
> got it working for opEquals, a simplified example:
>
> foreach(network; db["networks"].each) {
> writefln("network: %s", network.name);
> foreach(host; db["hosts"].where(db.c.id == network.id)) {
> writefln("\thost: %s", host.address);
> }
> }
>
> This works because db.c.id returns a struct which defines an opEquals
> which returns a "Filter" struct, rather than an int. I'm not positive
> that it should really be allowed by the compiler, but it works:
>
> struct Filter { ... }
> struct Column {
> Filter opEquals(T)(T rhs) { ... }
> }
>
> Then the .where call takes a filter, and uses it to output a snippet of
> sql like "id = 5"
>
> However, this won't work for comparison operators like < and >, which
> all map to opCmp, or for != (since that's rewritten to !(a == b))
>
> I guess I have two questions, one, am I going to shoot myself in the
> foot by going down this path, because it only happens to work due to the
> compiler being too lax? And is there interest in extending D to allow
> the rest of the operators to return non-boolean results? I'm thinking
> something like falling back to opBinary!("<"), etc, if opCmp isn't
> defined for a struct.

I don't think this is EVER what you really want.
I believe that if you think you want this feature, 100% of the time, 
what you really want is a syntax tree of the entire expression. That is, 
either you want ">" to be a comparison, and "+" to be an addition, OR 
you want a syntax tree.





More information about the Digitalmars-d mailing list