
Andy, I'm impressed with the thought and effort you're putting into this. Keep it up. "Andy Little" <andy@servocomm.freeserve.co.uk> writes:
Is there not a universal syntax for C++ concept documentation to which everyone should conform or in which every construct can be expressed?
Every construct? Probably not. I can't prove that the existing idioms cover everything, including constraints I've never seen. However, they cover most things and you're not doing anything so exotic that it shouldn't fit. FWIW, once we have concept support in the language we will be using pseudosignatures rather than valid expressions to express syntactic constraints, so we can expect that to change. In the meantime, though, the things that can be expressed using established conventions should be so expressed.
PQS uses both forms of Concept. Is there any means or language convention to distinguish the two forms?
There are not really two different forms AFAICT.
OK. I have difficulties with that because it seems to contradict your remark about **in the context of MPL**. MPL is exclusively a compile time library. The TMP in PQS borrows heavily form MPL.
All that means is that when you're reading the docs for an MPL metafunction and you see foo<...>::type and have a "Type" column header, you know you're dealing with a type member and not a value member, and you don't need further disambiguation. That's ALL it means. So if you want to avoid ambiguity there, say your "compile-time" templates are MPL metafunctions. Well, you'd better make sure they _are_ metafunctions first :)
If I implement more planned features of the PQS library, I will need runtime and compile time versions of many Concepts. An example of this is (lets call it ) DimensionA Concept which in the TMP book Dimensional Analysis example is modelled by the mpl::vector of dimensional exponents.
In PQS it is also desirable to have a runtime version, this time modelled (say for simplicity) by something encapsulating a std::vector<int>. This would be a model of (lets call it) DimensionB.
The two Concepts need to be distinguished. I'm not sure if there is a naming convention in use to distinguish the two.
Static vs. Dynamic.
I thought of a Meta prefix for the DimensionA category (MetaDimension) and none for the latter (just Dimension).
It's not really meta.
OTOH I thought of a namespace prefix meta::Dimension, but I think that would be unconventional. I read you werent happy about use of the word meta but it seems to have the right connotations to me
Not me. Meta implies that it will be operating on itself.
FWIW, Const might do but I think the difference between these two is not well described by that.
static :)
My current intention is to put the compile-time requirement Concepts under a separate section from the runtime requirement Concepts.
Almost every concept you write that has runtime requirements also has compile-time requirements, so I don't know if this division makes much sense. But I'm much more concerned with the contents of the concept descriptions than the order in which they're presented.
I have put my latest effort at getting one PQS Concept (AbstractQuantity) right, into the Boost vault in Physical Quantities Units/ AbstractQuantity.html. http://tinyurl.com/7m5l8
BTW I am aware the formatting is poor, and external links go nowhere but currently I am just trying to get the syntax right (or more accurately the right ballpark)
This concerns me: A model of AbstractQuantity is also either a model of NamedQuantity or of AnonymousQuantity. Types modelling NamedQuantity are usually created by the programmer, while types modelling AnonymousQuantity usually arise as temporary results of calculations, somewhat analogous to L-values and R-values). AFAIK there's no precedent for a concept that sometimes refines one concept and sometimes refines another, but always refines one of them, and I think it will make things very difficult if you continue that way. What is an Entity Relationship Diagram? Do you possibly mean a diagram of concept refinement? If so, why not just say that? I don't know what I'm supposed to see below "Notation," but it's completely unfamilar to me. Is there supposed to be a table somewhere? It looks like: Notation In the AbstractQuantity Synopsis and functions tables Lhs and Rhs and Q are types that are models of AbstractQuantity and R is type that is a model of Rational. AbstractQuantity Synopsis a::divides,Rhs>; concept AbstractQuantity{}; Requirements: meta::binary_operation<Lhs,meta::plus,Rhs>; meta::binary_operation<Lhs,meta::minus,Rhs>; meta::binary_operation<Lhs,meta::times,Rhs>; meta::binary_operation<Lhs,met meta::binary_operation<Q,meta::pow,R>; meta::dimension<Q>; meta::dimensionally_equivalent<Lhs,Rhs>; meta::is_dimensionless<Q>; meta::is_named_quantity<Q>; meta::is_anonymous_quantity<Q>; meta::is_same_quantity<Lhs,Rhs>; Notes Math on the associated Dimension of an AbstractQuantity works logarithmically, so addition and subtraction of the DimensionalExponents of a Dimension transform to no-ops ( the types of dimension<Lhs> and dimension<Rhs> are required to be dimensionally equivalent), multiplication to addition, division to subtraction and raising to a power to multiplication. Functions meta::binary_operation<Lhs,meta::plus,Rhs> </ Description: Returns the type resulting from addition of 2 types modelling AbstractQuantity Expression: meta::binary_operation<Lhs,meta::plus,Rhs>::type Requires: dimensionally-equivalent<Lhs,Rhs> models True Returns: A model of AbstractQuantity Q where: dimensionally-equivalent<Q,Lhs > models True. And dimensionally-equivalent<Q,Rhs > models True. And ( If same_quantity<Lhs,Rhs> models True Then same_quantity<Q,Lhs> models True Else is_anonymous_quantity<Q> models True.)
FWIW in rewriting PQS library, I am now aiming to make the Concepts wide enough so that the examples using mpl::vectors in TMP book should work though they will need specialisations(overloads?) of the metafunctions in the PQS Requirements to work of course.
Sorry, not "of course," because you lost me. Make concepts wide? You mean the tables? Some examples from the TMP book should work with PQS? How?
I guess this may have been what you were getting at in your review of PQS? IOW Some parts of the PQS library provide models of the Concepts, while other parts (metafunctions act in terms of Concepts) so can be applied to other models than the ones supplied.
Still lost.
------------
The following is some questions I am trying to answer. Maybe they just reflect my current confusion over this whole subject. Anyway I thought they might be interesting to see my struggles as a newcomer to this subject. I am currently looking over examples and may find answers to some questions there.
Questions resulting from trying to do the AbstractQuantity Concepts in the above mentioned AbstractQuantity.html
Associated metafunctions
1) Should I use the term return type with metafunctions?
e.g typedef f<T>::type result;
I see the above in terms of a function f returning a type, which IMO is quite acceptable in the TMP domain. I would then have a Returns clause in the specification describing the return type of f. It seems to be used this way in MPL docs anyway.
I would do whatever the MPL reference manual does, as long as you make it clear that the template is a metafunction.
2) Overloaded metafunctions.
I have overloaded? specialised?
Specialized of course. Where did you ever see the term "overload" applied to class templates? I understand that there's an analogy there, but it's not an exact one, and my whole point was that you shouldn't be inventing new naming conventions and notation in a domain where you don't yet feel very comfortable.
the metafunctions in a similar way to runtime functions are overloaded. An obvious example is the pqs::meta::binary_operation metafunction in the sample. This is meant to be entirely equivalent to runtime operator functions such as operator +. ( std::string + std:: string , int + int , IOW its just an operator)
Now however I need to express the overload of the Concept arguments.
Sorry, I'm lost again. Why not revert to standard terminology? What is a "concept argument?" Concepts are neither types nor templates (unless you mean concept checking classes, which I again highly recommend you write), so I don't see how they can either be or have arguments.
The way it seems to be done is to put in some Preamble (Sometimes called Notation?) that in the following, Lhs and Rhs are models of Concept X.
That's a familiar idiom before a concept requirements table, yes.
The problem is that is remote from the per item description:
binary_operation<Lhs,Op,Rhs>
IMO It would make more sense to say e.g.
binary_operation<AbstractQuantity Lhs,Op,AbstractQuantity Rhs>
Maybe it would (in fact something like that will be available with the language support for concepts), but as I said this is not the time to invent new notations. Get comfortable with the existing conventions first. If you wanted to look at ConceptGCC and actually write conforming new-style concepts, I'd find it hard to fault you... but I don't think that would be as useful to your readers, and for you I think that might be overreaching at this stage.
3) Why no BooleanConstant Concept?
boost::typetraits uses true_type_or_false_type. MPL uses IntegralConstant Concept. Should there be a (say) BooleanConstant Concept?
Why? Do you have some code that needs an IntegralConstant whose values can only be true or false (I.e. the code won't work as expected if the value is 2)? If so, you might consider a BooleanConstant concept. But you might also consider just making the code work right when the value is 2.
(Also IMO then there should be a True Concept and a False concept)
The existence of concepts is driven by the requirements of generic code. If you don't have code that requires a type's conformance to these properties, don't make a concept. Also, some concepts don't need to be separately named. For example, you can say "a nonzero-valued MPL IntegralConstant" or "a true-valued MPL IntegralConstant" when you mean the True concept. Whether it's worthwhile to make a separate True concept might depend on how often you find yourself needing it in your documentation.
This would be more generic and could apply to MPL and type_traits return types.
More generic how?
4)Am I right in saying there is a fair amount of variability in Concept documentation?.
Sorry, it's too subjective a question for me to answer definitively. I'd guess that most concept documentation exists at Boost. There is some poor concept documentation out there, and also some in here.
It strikes me that there could be a more abstract syntax to describe Concepts. Many times I want to say for example:
T Is True , meaning that in code where true_ is some model of True then one (among several) ways for a type t to model this Concept is
struct c : true_ {};
I usually say a "true-valued IntegralConstant" for that. You don't need to invent a more abstract syntax to describe that True concept. The standard requirements table and other notations will do just fine: True Concept Refines: IntegralConstant Requirements: In the table below, T is a model of True. +--------------------+--------------------+ |Expression |Semantics | +====================+====================+ |T::value |nonzero | +--------------------+--------------------+ -- Dave Abrahams Boost Consulting www.boost-consulting.com