Boost logo

Boost :

Subject: Re: [boost] [guidelines] why template errors suck
From: David Abrahams (dave_at_[hidden])
Date: 2010-09-27 17:06:33


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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk