
On Wed, 19 May 2010, Eric Niebler wrote:
On 5/19/2010 2:25 PM, Jeremiah Willcock wrote:
On Wed, 19 May 2010, Eric Niebler wrote:
On 5/19/2010 2:08 PM, Marco wrote:
I am a bit surprised by:
// These should be ambiguous. BOOST_MPL_ASSERT((is_same<deduce_domain3<DD1, DD0, DD0>::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same<deduce_domain3<DD0, DD1, DD0>::type, not_a_domain>)); BOOST_MPL_ASSERT((is_same<deduce_domain3<DD0, DD0, DD1>::type, not_a_domain>));
I was expecting something like: BOOST_MPL_ASSERT((is_same<deduce_domain3<DD1, DD0, DD0>::type, default_domain));
Am I missing something ?
This is a tricky case, and to understand why I want that result, you need to know what proto uses domains for. In proto, you put an expression in a domain to give it certain domain-specific behaviors. (E.g. lambda expressions should have an operator() that evaluates the lambda.) However, there are no domain-specific behaviors to the default_domain. (E.g. "42" is in the default_domain. Obviously, it has no domain-specific behavior itself, but "lambda::_1 + 42" should be in the lambda domain.)
If you combine two expressions in different domains, and the only super-domain they have in common is default_domain, then that would effectively strip all domain-specific behavior from the new expression. IMO, this would be surprising. Instead, I'd rather make this case ambiguous -- proto doesn't know what domain-specific behaviors to give the new expression so it gives up.
I acknowledge that it is a special case and that this result doesn't follow naturally from the other rules.
How do the rules for default_domain (and domains derived from it) fit into that picture? Expressions from different domains not derived from default_domain produce not_a_domain in the case of conflicts,
Right.
while a pair in which one element is derived from default_domain will always choose that element as the domain of the new expression.
Here, you mean "the other element" -- that is, the domain that is not a sub-domain of default_domain. The family of domains rooted at default_domain is weaker than all others.
OK. I implemented it the other way around -- choose the default_domain-derived domain if the other one isn't derived from that base. The two cases to flip to fix that are the second and third specializations of deduce_domain2_cases.
In my implementation, if both domains derive from default_domain but are otherwise incompatible, the result will be default_domain,
That's not right for the reason I stated above. And that's the case that hung me up for a while.
What do you want there? not_a_domain? Is default_domain itself a domain that's accessible to users (i.e., they can have an element with default_domain as its domain)? In that case, when do two domains that both derive from default_domain conflict? They have a common ancestor, namely default_domain. Or should default_domain be special in that regard, with a rule such as "if the merger of two domains is default_domain but one of them isn't default_domain, replace the result with not_a_domain"?
but normal domains do not derive from default_domain and so end up with the not_a_domain behavior in the case of conflicts.
This part is right.
OK. -- Jeremiah Willcock