
On Tue, Sep 28, 2010 at 10:45 AM, Mathias Gaunard <mathias.gaunard@ens-lyon.org> wrote:
On 28/09/10 18:33, David Abrahams wrote:
At Tue, 28 Sep 2010 10:00:54 -0500, Andrew Sutton wrote:
It seems to me that writing constraints in terms of valid expressions gives you flexibility when you want it, but doesn't preclude the strengthening of requirements when needed.
It's not that there's anything you *can't* express with valid expressions, it's that they're difficult to use correctly, and the most natural way of using them creates a big mess for algorithm writers. Furthermore, they don't offer any compelling value over the alternative.
Please demonstrate how you check that a type models a concept without using a set of valid expressions to define the concept, but only with signatures in an archetype-like fashion.
See 14.9.2.1 [concept.map.fct]p4 in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2773.pdf
My insight is that you can't.
There are several ways to accomplish this. The concepts proposal cited above mapped signatures to valid expressions when checking a type against a concept, but one could also perform a signature match with varying degrees of "fuzziness" (for references, convertibility, etc.).
Therefore what compelling value expressions give over archetypes becomes fairly obvious: they do what we want, while archetypes don't and do something different.
Having spent several years engrossed in concepts, I can tell you outright that valid expressions rarely "do what we want" from the type-checking perspective. There's a simple example from earlier in this thread:
bool(f != l) bool(p(*f))
Isn't bool(x) equivalent to (bool)x? I think that's valid code for any x.
That's valid code for any object x of a built-in type or that is implicitly convertible to any built-in type.
Since the valid expression has the conversion written explicitly, as a function-style cast, a class type with an explicit conversion to bool (or any built-in type) would also meet the requirements of this valid expression. The obvious point here is that the simplest valid expression we've seen in this discussion has already been misinterpreted. But, that's not the interesting part. Say we have values "f" and "l" in a constrained template with the valid expression "bool(f != l)". What can we write in the constrained template, such that we're sure it will instantiate correctly? bool(f != l) Yep, that works. It's just like the valid expression shows. (bool)(f != l) Yep, that works, since function-style and C-style casts have the same behavior. if (f != l) Yes, that works, because this is contextual conversion to bool, so explicit conversion operators will be considered. bool result = f != l; Nope, doesn't work, because we only said that we require an explicit cast to "bool" to work. The constrained template must be considered ill-formed, or you've lost type soundness. if (!(f != l)) Nope, doesn't work, because we only said that f != l must be explicitly convertible to bool; we didn't say that it needed to have a valid ! operator. some_function_template(f != l); // where template<typename T> void some_function_template(T); what does 'T' deduce to in this case? How would we describe the other requirements on the result type of f != l, so that we could ensure that the we meet some_function_template's constraints on 'T'?
You said it yourself: expressions are only half the solution; archetypes are the other half. They're not the whole and they're no substitute for using expressions to define and test concepts.
The whole point of concepts is that they have to be both. One description allows you to type-check a template definition and check a type against the requirements of a concept, and when both pass, you want to guarantee that the template instantiates property. That's type-soundness, and it is a fundamental goal of concepts. Valid expressions are fine for checking whether a type conforms to a concept, but they're poor at describing requirements for type-checking templates. Signatures naturally support type-checking in templates, and also make it fairly easy to check whether a type conforms to a concept. - Doug