
Sorry, I sent my previous email before completing it by mistake--I'm re-sending it. On Tue, Oct 2, 2012 at 9:27 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
On Tue, Oct 2, 2012 at 8:07 AM, Andrew Sutton <asutton.list@gmail.com> wrote:
However, syntactically you use it similarly to a template:
MyConcept<T1, T2, T3>
my_template<T1, T2, T3>
Syntactically yes, but they are allowed to mean very different things.
concept <typename T> EqualityComparable = ... // (3)
Actually, this would make the most sense to me, why wouldn't we use this syntax (3)?
Alex wanted the syntax to reflect, to some extent, the style that he used to define concepts in Elements of Programming.
In any case, why is (2) better than (3)? What was the rationale for such a syntax in Elements of Programming? (At the end I can adopt whatever syntax but I will need to justify the choice in a "rationale" section.) template< typename T > concept EqualityComparable = ... // (1) no good because concepts are not templates concept EqualityComparable< typename T > = ... // (2) concept <typename T> EqualityComparable = ... // (3)
A concept is a
type predicate (function) defined by a conjunction of syntactic and semantic requirements. Compare:
// EoP (with pseudo-C++ syntax) Relation(Op) = Predicate(Op) && HomogeneousFunction(Op) && Arity(Op) == 2
// N3351 concept Relation<typename Op, typename T> = Predicate<Op, T, T>;
In the writing, we wanted to emphasize the idea that a concept was "just" a predicate on template arguments. That made it easier to focus on the algorithm's requirements rather than to figure out the extensive set of language rules that would make it work.
But already the fact that the first argument of a concept is automatically replaced with the type when concepts are used in template parameter declarations:
template< typename T, Relation<T> Op > void func ( ... )
Already requires to know something special about the language that makes concept work.
Thanks, --Lorenzo