From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2002-08-12 23:35:18
>From: "Andrei Alexandrescu" <andrewalex_at_[hidden]>
> "Terje Slettebø" <tslettebo_at_[hidden]> wrote in message
> >Take one of the simplest algorithms, factorial.<
> This example has two problems: (1) it's not a "real-world" example because
> don't find myself running around and computing factorials of all possible
> 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.
> >Using MPL, you might write it like as follows. Explanation for the
> increase in complexity, follows below here. It is to get the same generic
> quality as the run-time version.<
> template<class V>
> struct factorial
> typedef typename V::type Value;
> typedef typename apply_if<equal_to<Value,value<Value,0> >,
> mul<Value,factorial<prev<Value> > >
> >::type type;
> That's it, 9 lines of code (7 without braces), one template, two typedefs,
> done. :)<
> ...relying on a ton of scaffolding, some of which doesn't even exist!
Yep, it does. So does C++, compared to the assembly code it's translated
too. However, the higher level of abstraction also gives it its power.
It's similar with metaprogramming.
>No more questions, your honor. I rest my case.
> Besides, I frankly find the code abominable. It attempts to look and feel
> like runtime C++, and to me it doesn't do it.
Well, I guess this is subjective.
Of course, you're free to use "metaprogramming assembler", too.
> >It could have been written simpler, using "*", "-", etc., if you assumed
> value passed in was int, or int_c, or something like that. However, with
> above form, it may be used to compute the factorial of any value type,
> as integral_c, fixed_c and rational_c.<
> But who wants to compute factorials at compile time for so many types?
> is the "real world" feel in this example?
> >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...
The smiley means I find this cool.
> [I will snip the long explanation you provide for the *simplest* example,
> factorial, implemented in MPL. Using some of MPL. Using some not yet
> parts of MPL. Using some novel ideas of your own. Using a hard to follow
> syntax. I repeat, if that's the *simplest* example, we're really in bad
> shape here.]
You know as well as I, that the features we have available at compile-time,
are different and less that what we have at run-time. There's no operator
overloading, for example, so if you want to make a generic routine, you
can't usually use infix operators, but have to use function-syntax.
Therefore, comparing this example to run-time programming, would be, as
you've said it regarding comparing it to Loki, a red herring. It wouldn't be
comparing like with like. If you want to compare the above to something,
then you should compare it to implementing the same functionality, without
The above was a simple _function_. I didn't say it was a simple example. It
uses advanced metaprogramming, much of it hidden in the library.
It was to use a simple function, to show the power of abstraction in MPL.
David B. Held also commented that he found this example interesting. And
that he would like to see it implemented without using MPL. So would I.
> >Enough of that version.<
> Agreed :o).
> >Let's look at the typical way it might be done using
> template specialisations. Feel free to make another version, here, Andrei.
> After all, this is your part of the argument. :)<
> Your code is fine.
> >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.
This was a simple mathematical function. Surely, if you can't get that to
work, how can you hope to come up with realistic, real-world examples?
> Anyway, the example does not justify the existence of various containers
> MPL; it only says that some of MPL's utilities are useful.
> >When it comes to the request of showing how MPL may solve a real-life
> problem, I think it's pertinent to mention that larger programs typically
> consist of smaller parts. Therefore, unless you get the smaller parts to
> work, the larger program won't work, either.<
> My point exactly :o).
Although you may have missed mine. How would you create a generic function
like the above? I.e. something that may be used for any value type. It's
decoupled from the value type, in a similar way to that the sequences are
decoupled from the algorithms.
You keep asking for real-world examples. What would be an example of a
metaprogramming task, that you would like to do? Let's get concrete, here.
Sure, you might point to the Loki components. They could also been rewritten
using the MPL functionality. Although it probably wouldn't have been much
point, as they don't rely that heavily on metaprogramming, so the Loki
typelists, hierarchy generators, etc. work fine for them.
However, if you were to do more advanced metaprograms, things may be
different. So since you want examples, what do you suggest to implement?
> >> That doesn't, in and of itself, really say anything. Of course what's
> > familar is also easiest. I think that a newcomer, however, can be
> > comfortable very soon with using dot-typelists than with an extremely
> > complicated incomplete compile-time emulation of the STL.<
> >I think it would be better to ask newcomers that. :) I don't think that
> given. As mentioned, it may well be the other way around.
> Similar arguments have been used to argue for teaching C++ the C-first
> as the standard library and STL was considered "advanced". When the truth
> that if you teach C++ as a high-level language, starting very early with
> standard library and STL, people tend to find it easier to learn good
> programming that way, than having to suffer through low-level C, first.
> I think it may be similar with MPL. It provides an additional abstraction,
> 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 people
> have to suffer when things can be done easier.
Well, it seems we agree on the last point, why suffer when it may be done
easier. I guess the question is what is the easiest way. :)
> Again, let's steer away from comparisons and see facts for what they are.
> >> My opinion is that C++ will never be there, simply because its template
> > engine is very different, and much more scarce, than its runtime
> > counterpart. That's why MPL seems to me like an interpreter written in
> > or advanced threading in Visual Basic: wow, look, it can be done, how
> > quaint - but man, you just get that feeling that the tool is totally
> > inappropriate for the job. That's why I also wouldn't be keen of
> > manipulating collections of 10,000 types at compile time in C++.<
> >Well, as I understamd, MPL is being used in real-life. Dave Abrahams has
> mentioned using it, for example.<
> I didn't ever say MPL isn't used or can't be used.
No, but you've asked for real-life examples. Which I think is a fair
> >Perhaps my simple example above can shed some light on this.<
> No light to my sore eyes :o).
>Fortunately, no heat either :o).
Of course not. :) I'm working on the Loki port to Borland, and am
participating in maintaining Loki. I'm rather involved with Loki. So how
could I behave badly to you? :)
Like I've also mentioned in another posting, much of what I've learned about
metaprogramming, I've learned from "Modern C++ Design". So you have a lot of
credit for that. I've also learned a lot from Aleksey/Dave's MPL.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk