Boost logo

Boost :

From: Markus Werle (numerical.simulation_at_[hidden])
Date: 2008-03-15 18:03:28


Eric Niebler wrote:

> Markus Werle wrote:
>
>> Summary: I strongly vote against _arg, _left and _right.
>
> I tend to disagree about _arg, _left, and _right. Should I also remove
> the free functions proto::arg(), proto::left() and proto::right()?

Yes.

> It's
> true, you can use arg_c() for everything, but IMO you have to look
> closely to see and appreciate the difference between "arg_c<0>(expr)"
> and "arg_c<1>(expr)", but left(expr) and right(expr) are immediately
> recognizable and readable. And most C++ operators are binary.

OTOH I really got lost on my first reading due to the aliases everywhere.

>> 2. From a user's point of view I still cannot see the advantage
>> of using argSOME_NUMBER instead of arg_c<SOME_NUMBER>.
>> Couldn't you make arg_c<XX> a first class citizen of namespace proto?
>
> I can't because proto::arg_c already exists, and it's a free function.
> However, there is proto::_arg_c<>, which is a synonym for
> transform::arg_c<>.
> A word about that. Proto reuses names.

I tend to feel uncomfortable about this, but I have no perfect proposal
to make it better.

_arg_c<> is fine for me.

> proto::X is a function,
> proto::result_of::X is a metafunction that computes the result type of
> proto::X, proto::functional::X is the function object equivalent of X,
> and proto::transform::X is the primitive transform equivalent of X. You
> can't import all these namespaces without making X ambiguous. For the
> most part, you don't want to, but transforms are different. You very
> often want to be able to refer to arg_c the function and arg_c the
> transform in the same bit of code.

I guess that is why I get lost all the time: I read the code in the docs
and cannot guess from the name whether this is a typename or a
function or whatever and which namespace it belongs.

Just a daydream: What happens if it is this way:

proto::X is a function, proto::result_of::X_r is a metafunction that
computes the result type of proto::X, proto::functional::X_f is the
function object equivalent of X, and proto::transform::X_t is the primitive
transform equivalent of X.

Do we loose anything? Do we run into trouble?

> Qualification like "transform::arg_c"
> is tedious and makes transforms hard to read.

I agree. arc_c_t<1> then? hmm.

> That's why the transforms
> have equivalents in the proto namespace with a leading underscore.
>
> I've always felt this is a little unsavory, but I haven't thought of
> anything better. I'm open to suggestions.

Let me first try this week to live with proto as it is.
It is obvious that proto is the 70th stage of rethinking the
same thing over and over again, say: approximately perfect,
so probably it is more a matter of getting used to it
and how to document it.
OTOH I really feel uncomfortable about those identical names
in nested namespaces ... I want to rethink this.
I once had some mightmare with ADL in a similar context, but
I cannot remmeber exactly how it appeared and I am too stupid
to invent an example where an abiguity drops in, so probably
what I am saying here is FUD only and a matter of taste.

>> So even if it makes it easier to write the boilerplate parts
>> of proto itself, names based on MACROS are still evil enough to
>> remove them from the _interface_ and for me _argSOME_NUMBER
>> is part of the interface.
>
> Macros? These are not macros, they're typedefs.

I assumed they were generated by a macro until BOOST_PROTO_MAX_ARITY ...
I was preaching against that (inexistent?) macro.
Now I took a look at proto_fwd.hpp and found they are made by hand
and stop at 9. So now I really have a problem:
what happens if I need an arity of 120?
 
> So you also feel that typing transform:: over and over is a pain!

OTOH today I always explicitly qualify with the namespace in my
own code, using namespace alias if it gets too long ...

>> Eric, please classify right from the beginning, whether issue #2
>> takes on "bike shed characteristics" and/or disclose your
>> rationale for _argSOME_NUMBER.
>
> I'm really sorry now about that bike shed comment. :-(

Never mind. It is stored for eternity now, so we can come back to
it whenever we want :-P

> I may be wrong, but it's possible that after you write some transforms,
> your opinion on this issue will change. The qualification and the angle
> brackets really obscure what a transform is doing. Consider the
> difference between these two:
>
> Use only transform::arg_c<>:
> struct MakePair
> : when<
> function<terminal<make_pair_tag>, terminal<_>, terminal<_> >
> , make_pair(
> transform::arg_c<0>(transform::arg_c<1>)
> , transform::arg_c<0>(transform::arg_c<2>)
> )
> >
> {};
>
> Use shorter typedefs:
> struct MakePair
> : when<
> function<terminal<make_pair_tag>, terminal<_>, terminal<_> >
> , make_pair(_arg(_arg1), _arg(_arg2))
> >
> {};

struct MakePair
     : when<
             function<terminal<make_pair_tag>, terminal<_>, terminal<_> >
           , make_pair(
                 _arg_c<0>(_arg_c<1>)
               , _arg_c<0>(_arg_c<2>)
             )
>
     {};

is OK for me, but I understand your intention.
Those transforms kill me, but I need them.

The advantage of those numbers is: proto is a typelist tool.
If you see the index you do not mix it up.
With _arg I always have this second, where I translate it back to
_arg_c<0>, etc. At least during my approach to the docs those
aliases did not help me (but I do not fear nested templates).

> They mean the same thing, but the second is a vast improvement, IMO.
> Proto uses function types to compose primitive transforms. Too many ::'s
> and <>'s break it up and obscure the meaning.

Yes, templates should use [] instead of <>.

> If I get rid of the _argN typedefs, the examples in the documentation
> will look very imposing.

If those _argN scale up to N=300 or more I will not vote against them.
Otherwise if 9 is the maximum, I have a problem with that solution.

Markus


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