Boost logo

Boost :

From: Larry Evans (cppljevans_at_[hidden])
Date: 2008-03-03 15:54:42


On 03/03/08 00:21, Eric Niebler wrote:
> Larry Evans wrote:
>> If the template arguments are grammars then shift_right<L,R>::type is
>> not an expression type.
>
> Correct, it's a grammar type.
>
>> AFAICT, it's of no use.
>
> That's not true. The fact that shift_right<L,R>::type creates
> expressions when L and R are expressions, and grammars when L and R are
> grammars,

Are you saying shift_right<L,R>::type is a grammar when L and R are
grammars or did you mean shift_right<L,R> is a grammar when L and R
are grammars? If the latter, then what is shift_right<L,R>::type when
L and R are grammars? More specifically, is there any use (for
example, in code you or anyone else has written) of
shift_right<L,R>::type where L and R are grammars? If not, then,
shift_right<L,R>::type, where L and R are grammars, obviously has no
use. If yes, could you please post such code or give a link to it so
that I can better understand your meaning?

> is an important symmetry that is leveraged extensively within
> Proto. And what would the alternative be? To have two classes,
> expression::shift_right<> that generates expression types, and
> grammar::shift_right<> that creates grammar rules? This would surely be
> worse for users.

Could you explain why it would be worse? I can see that one downside of
the two-class solution would be requiring the user to remember which
of two namespaces to use under the two different circumstances. The
upside is that, although the user would be required to remember two
namespaces, he would only have to remember one in any particular
circumstance:

   1) circumstance 1: grammars:
      use grammar::shift_right<> with only grammar arguments.
   2) circumstance 2: expressions:
      use expression::shift_right<>:: with only expression arguments.

IOW, use different namespaces but the same template name for different
circumstances. The different namespace name reinforces different
circumstances so that the user doesn't inadvertently use the wrong
template name.

OTOH, for the current one-class solution, the user has to remember
the "kind" of template argument to use depends on whether or not he
intends to use the nested type or just the grammar itself:

   1) circumstance 1: grammars:
      use proto::shift_right<> with only grammar arguments.
   2) circumstance 2: expressions:
      use proto::shift_right<>::type with only expression arguments.

Note, there is no clue in the proto::shift_right name as to which
"kind" of template argument to use. This lack of any clues lead me to
mistakenly use grammar arguments to produce a an expression type, and I
don't remember seeing any documentation warning against this. In
summary, it's just too easy for the user (in particular a novice user)
to make the wrong assumption about what kind of argument to supply to
the "grammar" template.

As a side note: an alternative to using different namespaces in the
two-class solution would be using the same template name but with an
extra template parameter used to signal the intention. For example:

   enum grammar_or_expr
   { is_grammar
   , is_expr
   };

   template<grammar_or_expr GorE, class Left, class Right>
   shift_right;

Shift_right could then be specialized on is_expr to define the nested
type, and on the is_grammar to *not* define the nested type.

Of course that's not much different than the two-namespace approach;
so, I'm not sure which would be better.

> Why have two when one works just as well?

The one-class solution is likely to cause users to stumble (see my
last paragraph).

> Or are you suggesting something else?
>

I'm suggesting either the two class solution or (my 2nd choice) a
prominent warning in the documentation of grammar classes explaining
that the nested type is only useful when the actual template arguments
are expression types.

I believe this is important because I stumbled over this and had to
decipher the compiler error messages before I could figure out that L
and R in shift_right<L,R>::type had to be expression types. I believe
it's likely that, without either such prominent warning documentation
or a two-class template solution, other users (at least novice users)
would also stumble like I did.

-regards,
Larry


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