
Markus Werle wrote:
[ Sorry, gmane was down on Friday and I could not get access to another nntp access point during weekend ]
Eric Niebler
writes: Markus Werle wrote:
So what we really need together with the tutorials and the documentation is a wiki about the design and evolution of boost. Design rationales are good. A wiki might work, but a better place might be in a "Rationale" section in each Boost library's documentation.
The advantage of a wiki (or any other public read/write access documentation) is that not only the designer of some boost part is in the role of an author for his design rationales but others can easily contribute.
True dat.
More important than the design rationale for boost::XXX is the design rationale for some of the building blocks of it, and since these are used across several distinct library parts, we really need design rationales for _techniques_ used in boost, a meta-boost design rationale. (Common tricks like deep_copy in all its flavours etc.)
I sometimes come across a discusion which I feel to be important enough to be cut'n'pasted to a CMS, let it be wiki or joomla or whatever you like ...
Well, Boost has as wiki, so what's stopping you? :-)
Then Eric Niebler could explain in depth why he needs "static, aggregate initialization" in proto (see <http://thread.gmane.org/gmane.comp.parsers.spirit.devel/2886/focus=2890 ) and why mpl does not fit for proto. Static initialization in proto is important so that when DSEL authors declare their global primitives like _1, there are no global initialization order problems.
My skills are not such that this piece of information suffices as explanation about what was suboptimal and what was fixed. Going back to your code again ... maybe I catch the idea sometimes. Never saw that trick before.
What is better in
static type call(Expr const &expr) { type that = {proto::arg(expr)}; return that; }
than
static type call(Expr const &expr) { type that = proto::arg(expr); return that; }
?
Oh, nothing at all. The benefit comes when declaring global primitives. Consider this at namespace scope: namespace my { struct placeholder {}; proto::terminal<placeholder>::type const _ = {{}}; } If terminal<>::type were a type with a constructor, that constructor would have to run *sometime* and the placeholder wouldn't be usable until after that time. Trouble is, C++ makes very few promises about when that *sometime* is. In contrast, the code above requires no runtime initialization. The placeholder just *is*, and there is no time during your program's execution when it is invalid to use it.
The only problem I had using MPL with proto was compile-time performance problems when using MPL lambdas. In order to keep compile times down, I've replaced as much template meta-programming in proto as possible with preprocessor meta-programming.
Could you publish an article about that? Your article "Conditional Love: Foreach Redux" (http://www.artima.com/cppsource/foreach.html) is a good example about cool things that are hidden in some innocent looking piece of code. Reading the header file never would have exposed the things that matter (at least to me).
I don't think that would make for an interesting article. See below.
And proto is a bit of a special case since TMP-heavy libraries are built on top of proto, so the TMP overhead of proto itself should be as small as possible. MPL is a very nice abstraction, but it's not free. Ditto for Fusion.
This raises 2 questions for me:
1. Could these issues be fixed for mpl and fusion or are you really forced to create your own enhanced versions?
I'm not creating enhanced versions of mpl or fusion. I'm using the preprocessor to generate code that would do the same thing as an mpl or fusion algorithm invocation. More below ...
2. If you build your own high performance versions of typelist etc.: isn't fusion and/or mpl a good place to add them instead to "hide" them in proto - below xpressive?
<cite url="http://thread.gmane.org/ gmane.comp.parsers.spirit.devel/2886/focus=2890">
[...] proto::basic_expr<> is the central data container of proto. It's functionality very much resembles a fusion sequence </cite>
I think I've been unclear. In proto, I try to keep template instantiations down. One way I do that is by generating specialization with Boost.PP instead of calling mpl/fusion algorithms. Consider deep_copy(), which essentially applies a transform to each child of a node. There are at least two ways to do this: 1) The Easy Way: Use fusion::transform(). Done! 2) The Hard Way: write N specializations of deep_copy<Node> (where N is the maximum number of children a node can have), and do the transformation on each child directly. The only thing (2) has going for it is that it incurs fewer template instantiations. No fusion iterators, or transform_views, or miscellaneous traits like begin<>, end<>, equal_to<>, or anything else. But would I endorse (2)? No. Just like I wouldn't recommend programming in assembly, unless you really need that extra 5% speed.
And yes, I measure compile time performance and don't optimize prematurely.
I do not question what you are doing. I am simply looking forward to profit from the fact that you've been already there in compiler hell and are willing to give us some good advice how to survive when we go there, too.
I am probably asking too much here. It's only that I am not able to extract this knowledge from source code ...
I'm sorry to disappoint you, but there is probably no way you can profit from proto's innards.
P.S.: Apropos proto: are you planning to introduce a glommable disambiguation mechanism [Geoffrey Furnish]?
I Googled this: http://www.adtmag.com/joop/carticle.aspx?ID=627. IIUC, this is a way to control which sub-expressions can combine with which others, and with which operators. Proto can do this, and its mechanism is much more powerful and elegant, IMNSHO. You define the meta-grammar of your DSEL, and then you tell Proto that only expression types that conform to that meta-grammar are allowed. Operators that produce invalid expressions are not even considered. First read this ("Patterns and Meta-Grammars"): http://tinyurl.com/3akbtb Then this ("Extending Proto"): http://tinyurl.com/2xs222 HTH, -- Eric Niebler Boost Consulting www.boost-consulting.com