Boost logo

Boost :

From: David A. Greene (greened_at_[hidden])
Date: 2001-12-13 16:04:01


David Abrahams wrote:

> That is a linear structure. Yes, technically it's a tree, but you could also
> think of it as a chain with the types hanging off one level deep at each
> node in the chain. As Mat points out, Loki's result contains more
> intermediate classes, but it has essentially the same structure (that the
> types are "scattered" all over the page notwithstanding).

Yes, that's absolutely true, but Loki derives the structure
through recursion. Inheritance (to me) models at compile
time what functions do at run time. Thus recursion is a
natural way to think about these sorts of problems for me.

Of course YMMV.

> The typelists aren't implemented very differently in Loki and MPL. MPL just
> went a little further in generalizing them so that the same algorithms could
> work on other compile-time sequences.

I don't see anything wrong with that. Again, I simply
stated that Mat's code is rather complex -- too complex
IMHO to do something that is conceptually very simple.

>>not. Your version was clearer, but did require the
>>aggregation of several meatfunctions into one class.
>
> No, it didn't. That class represented a single metafunction object.

By "aggregation" I meant aggregating functionality, not objects.
I should have been more clear. Or maybe I don't understand
your solution as well as I thought.

>>>>I think it is somewhat deceptive. The names and arguments look
>>>>familiar, but the STL algorithms work smoothly because iteration
>>>>is a natural interface to containers/sequences.
>>>>
>>>That's somewhat presumptuous of you.
>>>
>>What's presumptuous? I'm sorry if I gave offense, that
>>was certainly not my intention. If I've got something
>>wrong, please correct me. I'm learning, so forgive an
>>intermediate-level Boost newbie.
>
> It seemed as though you were saying that either I was somehow deceived by
> the similarity of STL/MPL idioms or that I was trying to deceive others.

Oh no, not at all! I see how my statement could be read that
way, so I apologize for the ambiguity. Perhaps "seductive" is
a better word than "deceptive." I fear people unfamiliar with
MPL or metaprogramming in general (i.e. learners like myself)
will try to shoehorn certain metaprogramming tasks into an
STL-like formulation simply because MPL provides similar
constructs. It'll work, but I don't think that's always
the best way of doing things. I see metaprogramming as
being much more functional than imperative, but then again,
I have only studied metacode that maps nicely into a
functional formulation.

Now, I'm not arguing that MPL should or should not follow the STL
naming convention. I don't have enough experience to know.
I do know that when reading Mat's example I wasn't sure exactly
what for_each does and how it differs from for_loop. I have some
idea now but I'm not totally clear. Documentation will help
that. I was also confused by the overloading of "_1."

Part of the problem was the example's incompleteness. I
don't know what "Glue" is. I can guess, but there's no way
I can be sure. I realize that posting the entire code
probably isn't practical so I didn't comment on this in
my initial reaction.

> I did a LOT of heavy-duty metaprogramming with MPL, so I think my experience
> is valid. I certainly have no intention of deceiving others - I am putting
> this argument forth because the experience left a big impression on me.

Good! In that regard you have much more authority than I
do. As I said, I presented the first impressions of a
metaprogramming newbie.

>>a framework to allow recursive algorithms should be included.
>
> I think a framework to allow recursive algorithms is a subset of the
> framework in MPL. Basically, you get the "quoted" function object idiom, and
> that's it. You can always write your own recursive algorithms with MPL type
> lists. The termination are detected slightly differently to allow for
> different sequences, but that's about it.

Can we get examples of this? I'm still not clear on what a "quoted"
function object is. Obviously I need to study MPL in depth.
Unfortunately, time constraints don't allow me to do that right now.

>>Of course. MPL provides that. Loki provides another. I
>>just happen to think that some problems map better onto
>>recursion than iteration.
>
> No argument from me. I don't think GenScatterHierarchy is one of them,
> though ;-)

I guess I look at the code and decide from there. The Loki
implementation seems cleaner to me.

> I did write a number of recursive metafunctions with MPL also, FWIW. It
> became a last resort, though.

Why? I'm curious. Was it the type of problem you were trying
to solve?

>>Right! Keep for_each! I'm just asking for more options.
>
> You've got them. Anyone can ignore the algorithms and hand-code recursion if
> they so choose.

I assume things like GenScatterHierarchy will be provided by a patterns
or meta-algorithm Boost library. Algorithms are very, very nice,
but even STL doesn't work for everything.

>>Just as recursive functions have a termination condition,
>>recursive metaprograms have a termination specialization.
>
> Well, not neccessarily. Let's look at a normal recursive factorial function:
>
> int fact(int x)
> {
> return x == 1 ? x : x * fact(x - 1);
> }
>
> Note that the termination condition is NOT expressed by a separate copy of
> the function.

Ah, I didn't explain myself clearly enough. When I think about
recursion abstractly, I think of the termination code as a
separate function because at runtime the dynamic execution
path will be different. That's what I meant. I know the
static code is lumped together.

> You can do the same thing with metaprograms using a type_if
> construct. So you don't need a specialization for termination of a recursive
> algorithm. The separate copy for termination, although easier to code, is
> often harder to read.

This sounds interesting. Can you give an example? I agree
that coding a separate termination class can be more difficult
to read/maintain.

>>>What they have is a tree structure.
>>>
>>Which is a recursive structure. Child nodes are trees.
>
> Okay, I see now that this is just the way you think of it and not meant to
> correspond to any absolute reality ;-)

What do you mean be "reality?" They're just electrons in the
real world. ;) It is "just" the way I think of it, but
that's all any of us has to go on. There is no One True Way
to abstract programming concepts.

> No doubt. However, a type list is a linear (as opposed to a tree or graph)
> structure, so it lends itself to linear processing. There are all kinds of
> ways to stop partway through.

Yep, I understand what you're saying. Perhaps I am just caught
up by the fact that typelists are structured with (as I think
of it) recursive inheritance. It then seems natural to me to
use recursion to extract the information.

> think the binders and composers in Mat's original example made things look
> complicated to the point where they obscured the value of the MPL algorithm
> decomposition.

I agree 100% with this. Your solution did a lot to clear that
up, and your explanations (especially in this message) have
helped me understand things a bit better.

I'd like to see more examples of MPL. With recursion,
without recursion, maybe even comparing solutions
coded both ways. People familiar with Loki are going
to be overwhelmed by MPL. Give them something
familiar to compare and they'll be more willing
to examine closely. Ideally I'd like to see arguments
as to when and why MPL algorithms are useful. I am
willing to critique examples when I have the chance.
I would not want a new MPL user to judge it by Mat's
solution. That's not taking anything away from Mat.
But when teaching, simple is usually better.

                              -Dave

-- 
"Some little people have music in them, but Fats, he was all music,
  and you know how big he was."  --  James P. Johnson

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