On 8/31/2014 12:23 AM, Matt Calabrese wrote:
Design: As a set of utility macros, there is not too much to be said. The macros that are presented are generally useful and fill some needs that are encountered when doing preprocessor metaprogramming.
Implementation: I admittedly haven't examined the implementation itself too closely, but I have used the library in practice with both clang and gcc without problems on a considerably large preprocessor project (~50k lines preprocessor programming), albeit a few years ago.
Documentation: I read through the entirety of the documentation and it is fairly good at describing some of the problems faced when doing preprocessor metaprogramming, such as the lack of truly being able to detect emptiness and the implementation weaknesses of certain non-compliant preprocessors.
That said, I feel like it focuses a lot on the hairiness of the preprocessor and not enough on the functionality that the library itself provides. For example, the tuple-related macros (being able to deal with something that is a tuple with more tokens after the tuple, for instance) are very useful in preprocessor metaprogramming, but the documentation doesn't do much to explain why. As well, while what to expect from expansion of the macros is described, examples are absent.
To be more specific, take these two bits of the documentation: BOOST_VMD_BEGIN_TUPLE http://htmlpreview.github.io/?https://raw.githubusercontent.com/eldiener/var...
BOOST_VMD_AFTER_TUPLE http://htmlpreview.github.io/?https://raw.githubusercontent.com/eldiener/var...
Although the macros are described, a set of examples could go a long way. For instance something as simple as the following can go quite a long way: BOOST_VMD_AFTER_TUPLE( (int a, float b, char c) const ) // yields: const
The above both more directly shows what you can expect from the macro and also may better explain the usefulness.
I agree that I need to give more and better examples in the documentation for the use of each macro in the library.
To people experienced with [ab]using the preprocessor, why you want to use these macros is often obvious, but most people are not very familiar with preprocessor metaprogramming and I think the docs sort of need to be aware of that.
Agreed. I need to slow explain reasons for functionality better.
Examples and a motivation explaining why the particular set of macros provided is important. Perhaps what might be best is to start the documentation with a tutorial that takes the user through the uses that come up in practice when I.E. designing a simple EDSL through preprocessor metaprogramming.
The one reason why I generally do not like tutorials about using a library at the beginning of the documentation is that the end-user has not yet encountered the functionality of a library when the tutorial is explained. So all the terminology in the tutorial is strange to the end-user at that point. But a much better overview of VMD is needed at the beginning to explain why the library would be useful and I will definitely do that. Along with that overview I will add at least one extended example at the end of designing a simple EDSL through the preprocessor in order to give an understanding of what sort of preprocessor metaprogramming can be done with the facilities of VMD.
Usage: Years ago I used the VMD library when developing [not a boost lib] Boost.Generic. Prior to VMD being around, I had hand-rolled much of the functionality into Boost.Generic that VMD provides, though I very quickly stopped caring about VC++ support. When VMD was in the boost sandbox, I swapped out everything I could with invocations to VMD's macros and it freed me of the maintenance burden of trying to support noncompliant compilers. Needless to say, VMD "just worked" and I find it likely that other people who use the preprocessor in these ways would find VMD just as useful as I have. For my project I was testing with both GCC and Clang and had no problems with anything that VMD provided.
Domain familiarity: I've done an embarrassingly large amount of preprocessor metaprogramming and, again, I find this library useful.
=====
Overall, I'd say that this library should make it into boost. The biggest thing that it lacks is motivation in documentation, lack of examples, and a practical tutorial, but these should be able to be added before the library would make it into a release. Other than that, I do think there might be some way to roll this into Boost.Preprocessor, but I have no strong feelings on the matter and it's really up to Paul.
So this a +1 from me, as long as the documentation gets some improvement.
Thanks very much for your review. My updated documentation will have all the things you suggested, especially examples of practical use. I am glad you have found the library useful in your own programming.