
On Behalf Of Corwin Joy
Actually what I am talking about here is the situation where the user specifies the type of the target data at compile time.
I think what we have with the binding language isn't so much type safety as it is type consistency. If you specify that two fields are related with the binding language, we can ensure at compile time that they are the same types, for example. You could continue this with the query building language: field<std::string> name("Name"); field<double> salary("Salary"); BindEmployee(Employee &Emp, Bindings &cols) { cols[name] >> emp.Name; cols[salary] >> emp.Salary; } //compile time error std::string criteria = make_criteria(name == salary); Of course this is a little clumsy especially in that you lose automatic type deduction but maybe it would be worth it in some cases.
Personally, I quite like using operators for the binding syntax rather than function calls since I think this make it much easier to read what is going on.
Here is a second quickie example
// simple example for Local bindings ... read a map
map<string, double> ReadDataLocalBCASingleField() { typedef pair<string, double> rowtype; rowtype row; //
I agree. prototype We've been down some of the same paths. As it turns out almost everything I read from a database is read into a map. I got so tired of doing this that I finally wrote a map_pair_type<> template.
row object to guide binding process // declare our bindings locally
DBView<rowtype> view("EMPLOYEES", BCA(row, COLS["Name"] >> row.first && COLS["Salary"] >> row.second ) );
// copy the doubles from the view into the vector and return map<string, double> results(view.begin(), view.end()); return results; }
In my language this looks like: const serializer<rowtype> ser = table("EMPLOYEES") [ field("Name") = &rowtype::first, field("Salary") = &rowtype::second ]; return ser.load<map<string, double> >(database); Very similar!