
Jonathan Wakely wrote:
I'm very interested in this library and have some thoughts on Larry's reply.
A benefit of Domain-Specific Languages is that you can provide a more natural and expressive syntax for the domain. Since most people's experience of relational models involves SQL I think a syntax that (even vaguely) resembles SQL is better than what is pretty exclusively C++ syntax. Try getting a developer who prefers java to write all those angle brackets and double colons when they could just connect to an RDBMS with JDBC and run SQL queries at runtime (several orders of magnitude slower, of course :)
I am not sure how something like this would be structured, but what about something like Boost.Spirit/Phoenix/Lambda/Xpressive for SQL?
Also, many queries have a large number of conditions, so the C++ syntax will get very long and so is *much* harder to read (and write!)
As for avoiding macros, IMHO using macros is fine in this context. Macros are code-generators, and that's exactly what Calum's using them for. Again, there's no reason a declaration of a table in the DSL has to look like a C++ declaration.
Macros are useful tools - you only have to look at Boost.PreProcessor to see how powerful it can be! However, macros/preprocessor sould be, wherever possible, restricted to implementation (like Boost.Function). As I mentioned above, having a Boost.Spirit-style SQL syntax would complement the direction that C++/Boost is going with respect to describing external constructs (RegExes, BNFL grammars) within C++. The RML database and results could be kept in tuples, so CREATE TABLE would be: typedef boost::tuple< std::string, std::string, int > people_table; static const int first_name = 0; ... I only have limited knowledge of SQL syntax, but we could then have something like: rml::sql_statement results = select_( item_<first_name> && item_<last_name> ) .where_ [ item_<age> >= 30 ] BOOST_FOREACH( data = results( rml_database )) { std::cout << get<first_name>( data ) << std::endl; } - Reece