Domain Specific Languages in D; was: C++, D: Dinosaurs?

Marcin Kuszczak aarti_please_no at spam_interia.pl
Tue Nov 4 12:13:11 PST 2008


Julio César Carrascal Urquijo wrote:

> Hello Aarti_pl,
> 
>> Yes, something like this would be possible. But it would start to be
>> very complicated, unmanageable and not so useful soon. Implementing it
>> in such a way for every DSL will be very hard.
> 
> Fragment objects are used in SubSonic so I think it is manageable at least
> for the SQL case.

I didn't know about SubSonic. I was thinking that only project which tries to use OO SQL queries was Ultimate++. So, thanks for reference!

> One thing I should probably have shown in the example is that Fragment
> objects just route calls to the underlying Query object so they are small
> and don't have any logic:
> 
> class WhereFragment
> {
>     this(Query query) { m_query = query; }
> 
>     OrderByFragment OrderBy(Column[] columns)
>     { 
>         m_query.OrderBy(columns);
>     }
> 
>     Query m_query;
> }
> 
> In your case it would be a template of the Table class, of course. Also,
> you would need create a small number of them (WhereFragment,
> OrderByFragment, SelectFragment).

This is interesting technique. But also IMHO not always usable as you can not finish statement with  WhereFragment when your result is SelectStatement. Wait, I just realized that opImplicitCast will be also very helpful in this case as WhereFragment can be implicitly casted to Query :-D
 
>> Also there are cases in
>> normal programs where it would be useful to have such checks.
> 
> Agree. For example, GUI controls sometimes requires you to set several
> properties to specific values to get a specific effect. This could benefit
> from having this kind of support from the language. Though I don't think
> this is a pressing issue.
> 
> 
>> Currently I use simple runtime checks (somewhat simplified,
>> pseudocodish and not tested code below):
>> 
>> class SelectStatement {
>> string[] next;
>> this() {
>> next = ["Where", "From"]; //All possible options after
>> construction
>> }
>> public SelectStatement Where(SqlExpression exp) {
>> if ("Where" !in next) throw Exception("Syntax error");
>> ...
>> 
>> next = ["OrderBy"];
>> }
>> }
>> Probably it should be possible to implement something similar in
>> compiler to make checks on compile time. If some variable has assigned
>> object of such a class compiler should trace this variable and check
>> if methods are called properly (in order, that they *are* called etc.)
> 
> I would say that fragment objects are simpler than littering your methods
> with these checks.
> 

You are probably right here. But I don't have in Java and still in D opImplicitCast to the rescue and would have to add to fragments artificial e.g. .apply() method which would always return query.

My design is a bit different from SubSonic one. My queries are quite independent, and they do not evaluate automatically to results. They can instead be passed and modified in different places in program. When query is ready it can be changed into SQL by one of generators. Generator can create SQL for specific database. But it can also create hash to help caching queries. After that query is executed by one of available Executor.

So in my design artificial .apply() will not be very nice addition....
 
>>> You should probably do as LINQ to SQL and start the query with the
>>> FROM statement instead. That way you can cascade the type and help
>>> auto-complete in IDEs.
>>> 
>> Well, I don't see problem here with my approach... SQL has a lot of
>> options after SELECT keyword and before WHERE. How can I use them
>> using only From?
> 
> I meant something like this:
> 
> auto q = From(Employee)
>     .Where(Employee.Email, Is.EqualTo("jcarrascal at gm..."))
>     .Select(Employee.ID);
> 
> This way the Employee type in the From() would cascade to the Where() and
> the Select() and you could add compile time checks to allow only columns
> of that table to be used in there.
> 

I see. I took a bit different way in this case. In my design From is optional as all tables are inferred from Select() (every column have defined its table, so it it easy).

> One question: Do you library supports (inner/outer) Joins or have plans to
> support them?

Yes. I have added them lately.

> Thanks

-- 
Regards
Marcin Kuszczak (Aarti_pl)
-------------------------------------
Ask me why I believe in Jesus - http://www.zapytajmnie.com (en/pl)
Doost (port of few Boost libraries) - http://www.dsource.org/projects/doost/
-------------------------------------




More information about the Digitalmars-d mailing list