opEquals/opCmp returning other types

Brian Palmer brian+d at codekitchen.net
Sun Mar 18 17:54:27 PDT 2012


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.


More information about the Digitalmars-d mailing list