Don pisze:
aarti_pl wrote:
DSL support in mother language. As an example I can give SQL in D or
mockup tests description language (usually also in D - not as a
separate script language).
Could you be more specific about this? For SQL, arithmetic and
logical operators don't seem to be involved.
In fact they both can be involved. Below are operators which are
understood by SQLite - one of the simplest databases:
Binary:
||
* / %
+ -
<< >> & |
< <= > >=
= == != <> IN LIKE GLOB MATCH REGEXP
AND
OR
Unary:
- + ~ NOT
As you see there are arithmetic operators and as well logical
operators, which are used in SQL expressions.
The example you gave showed (if I understand correctly) a wish to
make expression templates involving comparison operators, a task
which is currently impossible.
Why do you mention expression templates? Its not necessary to use them
in my opinion. Operator overloading should be just right for this task.
It seems to be the same concept: the == operator does not perform an ==
comparison, rather the return value records the operands which were
used, and records the fact that an equality comparison needs to be made.
The actual equality comparison is done later, when the complete
expression is known (it is done in the SQL statement).
I see built-in operators overloading as a part of wider category of
defining infix functions (eventually also postfix functions).
It seems to be a case where you want an abstract syntax tree.
Abstract syntax tree can be quite easily created using concepts already
existing in D. Someone here on D newsgroup showed me a simple way using
"parts":
class Select {
SelectWherePart Where(Expression expr) {
return new SelectWherePart(expr);
}
FromPart From(FromExpression expr) {
return FromPart(expr);
}
}
Maybe it is not perfect, but should work reasonably well. Especially
with opImplicitCast and with operator overloading.
Also I would like to add a word to my latest post regarding string
mixins as I see I was not clear enough about it. It should be possible
to construct queries itself on runtime like below:
DbTable Person = ....; //In my case DbTable keeps table columns and
few other informations
DbMatrix getPersons(SQLExpression exp) {
Query query = Select(Person).Where(exp);
return Database.execute(query);
}
void main() {
SQLExpression exp = (Person.Name == "John");
DbMatrix res = getPersons(exp);
}
This is what I mean by constructing queries on runtime. With string
mixins you will have to do not only mixin(SQL("SELECT ....")) but also
mixin(SQLExpression()), what gets really complicated in the end.
No. You can always move the complexity into the mixin string parser.
(since you can get full type information of everything mentioned in the
string).
I don't think it is possible. Imagine that you have additionally
OrderByExpression and few others expressions like GroupByExpression etc.
Now you parser will have to guess what you need just using one method SQL():
mixin(SQL("SELECT * FROM a;")); // result: SelectQuery
mixin(SQL("Person.Name == i + 5")); // result: WhereExpression
mixin(SQL("Person.Surname ASC")); // result: OrderByExpression
I wouldn't want to write such a parser. And additionally probably some
expressions would be ambiguous.
But it is possible that I miss something here, so if possible please
provide usage examples. You can take e.g. above snippet with passing
SQLExpression into function.
BTW, the string mixin is just a temporary evil -- it's a way of getting
an abstract syntax tree using existing D. It's severely lacking syntax
sugar.
I don't know much about what will be cooked in future for D. But
listening to proposed features would be definitely interesting :-)
BR
Marcin Kuszczak
(aarti_pl)