Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2002-08-13 08:22:02

>From: "Paul Mensonides" <pmenso57_at_[hidden]>

> From: "Andrei Alexandrescu" <andrewalex_at_[hidden]>
> > This example has two problems: (1) it's not a "real-world" example
because I
> > don't find myself running around and computing factorials of all
> > types at compile time; (2) It doesn't justify MPL's design that imitates
> > STL's design; (3) it really works more against your viewpoint :o). Ok,
> > that's three problems.
> I run around (in circles) just computing factorials in my head. :)
> > That's it, 9 lines of code (7 without braces), one template, two
> > done. :)<
> >
> > ...relying on a ton of scaffolding, some of which doesn't even exist! No
> > more questions, your honor. I rest my case.
> This is not the part that bothers me. You can use some of MPL's
facilities in
> the above example (factorial) and implement the concept in a simpler
> For instance, you could get rid of the type abstraction if you wanted to,
> This is just putting pieces of the MPL together and nothing is forcing
anyone to
> do that.
> Granted, I don't think that calculating factorials at compile time is much
> than a neat trick, but the example could be extended to handle some type
> numeric computation that actually is useful.

Exactly. The factorial example was deliberatly selected as a simple example,
one of the simplest there is, typically used to introduce metaprogramming.
It was chosen to not take the focus away from something else - the
algorithmic abstraction.

Thus, criticising this example as not being a real-world example would miss
the target. As I said, and as you say here, you have to get the pieces to
work, if you're going to write a larger system with them.

Besides, there hasn't been a whole lot of concrete examples in this thread,
so I figured having something concrete to discuss could help keep the
discussion focused, and separate the real stuff from red herrings and
unproven stuff.

What I would now like to see, is, at least an outline of, an MPL without the
iterator concept. We could then use that as a basis for discussion. For
example, what would the interface to sequences, algorithms, etc. be. Without
this, I think it'll mostly just be the what-if's. We already have the MPL
example. To put it the way the critics have, I have yet to see a convincing
alternative to MPL.

To make any comparison easier, tasks to be accomplished, using the two
approaches, would also be useful.

> The most relevant problem with the example is that it has nothing to do
> sequences or containers--which is the primary thing that Andrei and I are
> debating.

Andrei also questions that example, so it was useful in itself.

> Of course, there are two other problems. This little factorial
> allows you to calculate a factorial of two compile-time constants:
> follows)
> factorial( constant, constant )
> What about these:
> factorial( constant, runtime-value )
> factorial( runtime-value, constant )

I understand, from your later posting, that you meant "pow" here.

What about them? We are talking about metaprogramming here, not run-time
programming. If you want to evaluate it using run-time values, then of
course the algorithm has to be run-time, as well.

This is no argument against "pow", as it's outside the scope of
metaprogramming. What's your point? And what would you suggest instead?

> The same goes for 'pow', which is more reasonable in general programming
> factorial.

Actually, I understand it wasn't obvious, but apart from using factorial as
a deliberatly simple example, I also used it because it's useful in it's own
right. It enables you to for example calculate the trigonometric functions,
using Taylor series, which was the primary reason I made it in the first
place. It's useful to have factorial, anyway, though.

You may wonder how to represent sin, cos, etc. in MPL? Well, see those
fixed_c (fixed point type, e.g. fixed_c<3,14159265>) and rational_c types?
They may be used for this.

Indeed, MPL is not only about sequences. This is just the beginning... :)

Having such floating point values, allows you to implement all kinds of
floating point functions, as well, such as the mentioned trigonometric
functions (including the inverses) pow, log, sqrt, etc.

Oh, and did I mention that the "pow" may be used for any types? :) This
means making "exp" is trivial:

template<class Value>
struct exp : pow<EValue,Value> {};

EValue could here be a floating-point representation of "e".

> > Besides, I frankly find the code abominable. It attempts to look and
> > like runtime C++, and to me it doesn't do it.
> In a sense, it does look like runtime use of the STL, but the problems are
> different. Most of it is about template indirection rather than
> > >For example, if you create a new value type, like double_prec, you can
> > it in the above function, unchanged. :)<
> >
> > The smilye says it all...
> Andrei, are you trying to say that computing a compile-time factorial of a
> floating-point number at compile-time is not worthwhile? :)
> It would be possible to implement arbitrary precision arithmetic at
> this way. --But these are all academic until such things are actually
> *necessary* to produce real runtime functionality with metaprogramming. I
> implement high-precision arithmetic this way, yes, but what's the point
unless I
> actually *need* it.
> > >Enough of that version.<
> >
> > Agreed :o).
> This is the most amusing email that I've read in days. :)

Perhaps I made it a little too easy for Andrei, here. However, I didn't
expect such a cheap point to be made from it. Or I would probably not have
said that. It was my opinion that that version was better, for reasons I've
shown above here. However, this is something both of you may not have
considered. Metaprogramming is not limited to integer calculation, or using
the built-in types, only.

Yes, I used a simpler version first, that Andrei found fine. However, it was
impossible to extend. You _could not_ make it work for anything else but
integer values. Like Aleksey has generalised MPL, after having had similar
finidings, it appears to me that some of the criticism may come from not
realising the possibilities. Possibilities where the "simple" ways simply
don't work.

Or result in ugly workarounds. Personally, I find having to have a sequence
converter to be a less elegant solution, than to have a uniform iterator
interface. For the same reason I would have found it inelegant in STL,
regardless of efficiency concerns.

> We have a massive
> difference in perspective here IMO, academic vs. practical.

I'm not clear who "we" you are talking about, here. You've expressed
understanding the usefulness of algorithmic abstraction, as elaborated on
above. Andrei still questions this. You both question the usefulness of the
iterator concept.

My example above, that Andrei was replying to, is such an example that
you've said shows useful MPL abstractions. So who are you agreeing with,

> > >Let's make one that works on int, only, first. Then we'll try to expand
> > ("try" being the operating word, here. :) ).<
> >
> > Do we ever try to expand it? I repeat, this is not a good example. Let's
> > to come up with an example of code that people might actually need.
> More importantly, this example has nothing to do with sequences.
> > Anyway, the example does not justify the existence of various containers
> > MPL; it only says that some of MPL's utilities are useful.
> >> I think it may be similar with MPL. It provides an additional
> > so you don't have to write the explicit specialisations, etc., but can
> > code in something that may be more familar, resembling run-time code.<
> >
> > The comparison doesn't hold. It's exactly the other way: why would
> > have to suffer when things can be done easier.
> >
> > Again, let's steer away from comparisons and see facts for what they
> I agree. The MPL should be able to stand on its own without the STL
backing it
> up.

True. However, much of the reasons for the power of MPL, is the same as the
reasons for it in STL, the abstract interface, where you're not limited to a
specific sequence, algorithm, value type, or whatever. This is an open-ended

> > >Well, as I understamd, MPL is being used in real-life. Dave Abrahams
> > mentioned using it, for example.<
> >
> > I didn't ever say MPL isn't used or can't be used.
> I'd like to point out also that Loki's typelists are used in real life
> Further, idioms implemented with typelists are used in real life, and Loki
> doesn't have sequence abstraction.

> The argument doesn't fly because bad code is
> being used all over the place ( not to say that the MPL is bad code for
what it
> is supposed to be doing! ).

I was just replying to the question for real-life examples. I didn't say
that Loki's typelists isn't used in real-life, as well. Indeed, I've used
them in my own programs. They worked well for that. However, I'm questioning
the extensibility of that way of doing things.

Furthermore, aren't you contradicting yourself, here? First you make the
point that Loki's typelists are being used, and then you say the argument
(about something being used) doesn't fly, as bad code is also being used.
Sure, but this is not an argument against a specific library. You can't use
the use of Loki as an argument for Loki, yet deny the same argument for MPL.
No having your cake and eat it too.

> The question is, could all of the uses of the MPL
> in Boost (in the Python lib, etc.) be recreated *without* sequence

Perhaps much of the current use could. However, there's the question of the
extensibility in this approach.

As Dave Abrahams replied in a posting, he has experience with a case where
they picked a typelist, to implement it. However, it may later turn out that
another sequence was better. If you hardwire it to a specific sequence, then
it's not possible to do it like this. Then you're stuck with a specific
performance characteristic, also with respect to compilers. Personally, I
would oppose a design that didn't let me use it on the system I use, which
is mostly Intel C++. On this system, vectors are very slow, if they work at



Boost list run by bdawes at, gregod at, cpdaniel at, john at