
At Mon, 27 Sep 2010 15:57:49 -0400, Eric Niebler wrote:
Oh, whoops. Replace RHSOfAssign with SpiritParser.
OK, that helps some. But SpiritParser is already defined above. I assume we can replace that definition with a forward declaration. I assume concepts can be forward declared.
Sorry, don't remember. But you could always put the concept maps last.
I described a recursive description of the SpiritParser concept and you showed one without any recursive property at all. :-P
Uhm, still not sure where the recursion is in your description.
Look again at my description at the top of this email. A SpiritParser is + a node with a plus tag where the child is a SpiritParser, or + a node with a right shift tag where both children are SpiritParsers, or ...
Recursive.
Duh! Sorry for vision failure.
There must be some recursive relationship, like "a SpiritParser is a SpiritNode<plus> /or/ a SpiritNode<right_shift> /or/ ..."
And that's not recursion.
It is, because your own SpiritNode concepts are defined in terms of the SpiritParser concept, closing the circle. Have you lost the thread of this conversation?
Do say that, you just use concept_maps to declare that SpiritNode<plus> models SpiritParser, etc.:
concept_map SpiritParser<SpiritNode<plus> > { // ... }
concept_map SpiritParser<SpiritNode<right_shift> > { // ... }
Not according to my reading of the standard. A concept_map is for mapping *types* to concepts, not *concepts* to concepts, as you appear to be doing here.
Sorry, I may have spelled it wrong, but you can do it. Concept map templates allow you to map types that satisfy given concepts to other concepts. There's an example on page 44 of http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2710.pdf
template <typename Node> requires SpiritNode<Node, plus> concept_map SpiritParser<Node> { // ... }
template <typename Node> requires SpiritNode<Node, right_shift> concept_map SpiritParser<Node> { // ... }
Ah, well this is interesting. I didn't know you could constrain a concept_map like that and overload them on the constraints. But I'm still confused. If we can make recursive concepts as you've suggested above (by renaming RHSOfAssign to SpiritParser and closing the loop), then is this step even needed?
Which step? Needed for what? I don't quite know what you're trying to accomplish yet.
which, as Sebastian has pointed out, were yanked from the concepts proposal.
With good reason.
Algorithmic complexity, IIRC.
Also there's no real-world scenario that can benefit from it. There's nothing that OR constraints could express that couldn't also be expressed with concept_maps, and once you got inside the constrained template you wouldn't be able to use any operations that aren't in the intersection of the constraints (remember that template bodies need to typecheck against their constraints).
The /intersection/?
Of course. How could you typecheck the body otherwise without causing a possible error at instantiation time?
This seems like a real problem then, doesn't it?
No, the answer is easy: don't put OR constraints in the language, because they don't work. They're the problem.
I want to say that a SpiritParser is a SpiritNode<plus> OR a SpiritNode<right_shift> OR a SpiritNode<terminal> (the plus and right_shift concepts being recursively defined in terms of SpiritParser,
I showed you how to handle it above. You're thinking about this the wrong way. Concepts are a rule-based system, and you're approaching them functionally. It's a totally different programming paradigm.
the terminal concept having little more than a value_type typedef and a member), the intersection of all those concepts would have exactly nothing. So I couldn't do anything with it from a constrained context. What have I missed? How is the SpiritParser concept you've defined above supposed to be used?
Heck if I know; it's your library, man! It's empty because I don't know what operations your operator= needs from it. -- Dave Abrahams BoostPro Computing http://www.boostpro.com