Boost logo

Boost Users :

Subject: Re: [Boost-users] [Tuple] What's the point?
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2009-07-10 18:37:16


On Fri, Jul 10, 2009 at 12:52 PM, JOAQUIN M. LOPEZ MUÑOZ<joaquin_at_[hidden]> wrote:
> ________________________________________
> De: boost-users-bounces_at_[hidden] [boost-users-bounces_at_[hidden]]
> En nombre de Zachary Turner [divisortheory_at_[hidden]]
> Enviado el: viernes, 10 de julio de 2009 19:44
> Para: boost-users_at_[hidden]
> Asunto: Re: [Boost-users] [Tuple] What's the point?
>
>> I consider it a C++ design problem that there are actually situations
>> where iterating over elements of a tuple is the "quickest" way to
>> accomplish something.  When you're iterating over a collection and
>> performing some operation on the items in the collection, the elements
>> neecssarily having something in common otherwise the operation
>> wouldn't make sense.  But at the same time, the common aspect is
>> determined by the function, not by any aspect of the types themselves.
>>  From a theoretical perspective I think it's better to approach this
>> with typeclasses
>
> C++0x concepts are very akin to type classes.
>

That's true, and they help in some ways. But it doesn't address other
aspects. I suppose my complaint with iterating over tuples is mostly
of a theoretical nature and maybe nobody really cares. But even so, I
think that tuples should be completely distinct from sequences, and
that anyone using a tuple should be required to know exactly how many
elements are in it, and the type of every element in order for it to
be possible to use the tuple. In a sense, allowing generic iteration
over the elements of a tuple allows one to treat different tuples
(including tuples of different lengths) as the same type, or at the
very least being able to use two tuples of different types without
realizing they're different types.

Once variadic templates are more widely supported, then I think there
will be even less of a case for "tuple-sequences", because most (all?)
of the things it makes simpler can be achieved more naturally with
v-templates.

If you have an arbitrarily sized collection of objects, then there
should at least be some kind of well-defined structure connecting the
types to each other. If you're going to iterate over these elements
and then perform a completely different action on each item, then
obviously you need to know what the individual items are to select the
appropriate action. On the other hand, if you're not going to be
performing a completely different action on them, but rather
performing the same action on all of them, then perhaps the action
you're trying to perform should accept the tuple as its argument and
let it decide what to do with each item. Of course, it will in turn
need to make the same decision, and either understand the structure or
pass it to something that does.

> On Fri, Jul 10, 2009 at 11:26 AM, Joel de Guzman<joel_at_[hidden]> wrote:
>>
>> functional languages if you need to manually operate on each element
>> of a tuple other methods are provided like matching. I actually think
>> that it might be possible to achieve some matching like constructs in
>> C++, but I don't think (?) much if any research has been devoted to
>> that.
> Erm... every sentence above begs the question: why?

? I'm not sure what you mean by this sentence begging the question of
why. If you know of any research that has been done regarding match
constructs in C++ then please refer me to it. But the reason I don't
think much has been done is because I've never heard of any. OTOH I
don't claim to be aware of everything going on in the C++ world, so
I'd be interested to read any such research you know of.

That being said, given the amount of progress that has been been made
regarding conditional constructs in lambda expressions, I think such
techniques could be extended to allow for matching as well. A match
is generally specified much like a switch statement anyway. For
example, consider:

boost::tuple<int, double, string> test(4, 3.0, "hello, world");

using boost::tuple;
using boost::tuple::match;
using boost::tuple::pattern;
using boost::tuple::_;

match(test)
| match_case( (7, _, _)
         -> (std::cout << "first arg is 7 and third arg is " <<
pattern::_3 << std::endl) )
| match_case( (_, 3.0, _)
         -> (std::cout << "second arg is 3.0" << std::endl) ) //this
one will match
| match_case( _
         -> (std::cout << "no match!" << std::endl) );

It might even be possible to bind variables in the match condition,
although I'm at a loss for how off the top of my head which is why I
just made placehlders _1, _2, and _3.
Anyway I haven't put a ton of thought into a workable, easy-to-read
syntax that's technically possible, but something similar to the above
should feasible. And a construct such as this is much clearer and
easier to read / understand IMO than iterating over sequences of
objects whose types presumably have nothing in common.

It's true the above construct does not address the same problem that
iterating over tuples addresses, but variadic templates pretty much
do. I've yet to find a situation where boost::tuple made my life
easier (apparently much like the original poster), so I only mention
matching so much because IMO they are exactly what *would* make them
useful.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net