
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of David Abrahams
It is understandable, but nevertheless wrong in my opinion, that authors of documentation assume the reader will read the whole thing, from the begin to the end, with devotion (and time). Typically I have a concrete problem, and now just need the right tool to solve it. Thus I don't want to understand for example the whole Boost PP library, but I just want to create a double-nested loop with simple content (just as an example). Giving me general advice about good programming style and how to use the library in a good way, not to use it for the wrong purposes, might at some time interest me, but this should go into some special section (actually, it would be good to have this general discussion for a library; but as I said, I believe it should go to its own place, with appropriate links to it).
Several people (including me) have had this discussion with Paul many times. Although I disagree with him about this, I respect Paul's point of view in the matter. I suggest, unless you can find some new angle to the argument, that nothing new will come of repeating what others before you have tried and failed at.
It isn't that I don't believe that this is a good thing; it is that I don't believe that it is _possible_ without much more writing than those who ask for it believe. It would, for example, make the documentation for the pp-lib much larger than all of the rest of the documentation for Boost combined. I don't think that it is legitimate for users to expect to be able to have all their problems solved by the library without putting some effort into learning the language in which it is written. The other side of the coin is that I don't think it is legitimate for users to use some parts of the library without putting in some effort to learn the conventions used by the library (the primary one being how it handles recursion from a client interface point of view). I don't think, for example, that it is a long jump from "I tried to use SEQ_FOR_EACH inside itself, and it didn't work" to the topical article about reentrancy. Most of the time I get these complaints, it is because the documentation doesn't start with a particular user's problem and provide a direct (or near direct) solution. Even attempting to do that is like trying to produce a comprehensive list of uses for looping constructs in programming language. Then I get complaints that the examples are too contrived. In essence, they don't produce a reusable result (i.e. a use case). Then I get complaints that the examples are too complex. I just don't think there is any way that I can win, and I get discouraged every time I try because nothing is ever good enough. Preprocessor metaprogramming has an inherently steep learning curve. I can't just make that disappear by using better words. No matter what I do, there will be someone who will complain. The root of such complaints is always (or nearly always) that I don't somehow magically make the learning curve disappear. That I don't provide some kind of tutorial that takes a user from absolutely basic concepts to advanced idioms--only with small progressive steps. I don't think that's possible, and if it is, I certainly don't know _how_ to do it (especially not without 500+ pages of prose).
A final word: I know it from myself (not regarding documentation, but articles) that we tend to make a big fuss about our products, how it relates to so much other things, and how much a proper understanding of our product will help so much the reader. So we tend to obscure that actually what we are doing is quite simple --- and can be used quite simply.
For most people, the PP lib gives the illusion of being quite simple and familiar, but then there are issues like this recursion thing that you ran into, which don't map neatly onto the ordinary programming paradigms we're used to. I think those phenomena are harder to explain simply.
That's true. However... 1) The lack of recursion (or infinite replacement) in macro expansion is a pretty fundamental concept that user's should already know *long* before they start throwing preprocessor metaprogramming at a problem. If the user doesn't know that, than the user *probably* (and I'm not pointing a finger at you Oliver) doesn't know the rest of C++ (including modern C++ idioms) well enough to really know if preprocessor metaprogramming is necessary or better than the alternatives. Preprocessor metaprogramming is used mostly (by far) by people that have already run smack into situations where it was necessary after exhausting all other possibilities (i.e. they couldn't do it any other "good" way). That is not to say that the use of preprocessor metaprogramming should always be a last resort. But, like anything else, it should be used only when it is "better" than all other alternatives. The problem is that it takes a significant degree of familiarity with other alternatives (like templates and template metaprogramming) to make that comparison--which is why the pp-lib docs don't shy away from templates. 2) IMO, the "Reentrancy" article in the documentation does a pretty good job of explaining the library's conventions in this regard. Regards, Paul Mensonides