> lambdas
Lambdas in the host language won't play well with remote RDBMSes -- you'd have to be able to serialize the lambda and make the serialized form reasonably efficient. I'm skeptical of lambdas for expressions in DB query APIs.
An expression like `foo + bar` has to become `.expr(plus("foo", "bar"))`, except, if you take this to its limit you'll want to use non-string objects to identify column names and other such things, and, again, it quickly becomes unwieldy.
You cover some of this in your comment, so I think we're in agreement:
> That "the API becomes unwieldy" is in fact inevitable.
And yet an API is kinda desirable.
Ultimately I think a query language with no constant literals, only query parameters, compiling to a standard AST that can also be constructed by APIs, may be the best way forward. One could then write in a QL to start with, compile to an AST, serialize into a host language if desired, modify and use that, or always use the QL, or even always use the API, unwieldy though it would be. Then lambdas could actually be in the QL and compiled on the fly as needed:
Query q = db.query();
q = q.from(...).join(...).using(...)
.select(...);
q = q.where(q.expr("foo + bar < baz"));
Ok, that snippet has a problem if we want `q` to be a unique pointer. Let's fix it up a bit:
QueryScope qs;
Query q = db.query();
q = q.from(...).join(...).using(...)
.select(...);
/* Get a context of in-scope identifiers, types, ... */
qs = q.getWhereScope();
/* Now we can compile an expression string */
q = q.where(qc.expr("foo + bar < baz"));
And a hybrid QL + API might look like:
QueryScope qs;
Query q = db.parse("SELECT ... FROM ... JOIN ... USING (...)");
/* Get a context of in-scope identifiers, types, ... */
qs = q.getWhereScope();
/* Now we can compile an expression string */
q = q.where(qc.expr("foo + bar < baz"));