On Aug 13, 2015 3:45 PM, "Eric Niebler"
AFAICT, Peter's code is basically a work-alike of my Meta library [^1] with one feature added (the ability to treat any template instance as a typelist), and one feature removed (metafunction classes and their associated utilities).
I really believe losing metafunction classes is a significant loss -- not so much because template template parameters are so awful (but they kind of are), but because all the functional composition utilities (bind, compose, curry, uncurry, on, etc.) are so incredibly useful. And also because core issue #1430 [^2] makes it impossible to handle variadic and fixed-arity template aliases uniformly.
Meta's approach -- borrowed from the MPL -- of quoting template template parameters to turn them into metafunction classes (aka alias classes) puts the workaround for #1430 in one place so that it can be ignored and forgotten.
But in the end, Peter's and my thinking is pretty aligned wrt metaprogramming in C++11 and beyond.
[1]: https://github.com/ericniebler/meta [2]: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430
After maturing my understanding of metaprogramming a little further, I come to the conclusion eager metafunction evaluation using template aliases and lazy metafunction evaluation through explicit access of a nested ::type are two sides of the same coin and choosing one over the other is mostly just a matter of taste. That said, I'd like to share two reasons why I prefer the lazy version: 1. Most tools for metaprogramming in the standard library are lazy, so following the principle of least surprise, lazy it shall remain 2. Lazy evaluation of metafunctions allow for expressive construction of "lambda expressions" as formalized by MPL I concur with Eric that functional composition is a killer feature and I strongly believe it should constitute the very core of any metaprogramming library. I just go a step further and greatly simplify things by getting rid of "metafunction classes" altogether. I've managed to transfer the entire burden of abstraction to an analogous of MPL's apply, which expects a "lambda expression" and a set of arguments and, through a handful of partial specializations, directly evaluates it. Atop apply<>, bind<> becomes a one-liner, as do everything else just as gracefully. Oh and this way one also avoids dealing with core issue #1430, since MPL's quote<> is no more. If one looks closer, by doing the actual recursive metafunction evaluation in a SFINAE context behind the scenes, apply<> becomes a monadic bind of metafunctions, which, from this perspective, are themselves nothing more than optionals. Such concepts bring great expressiveness to a functional world. I've been exploring this idea with my library Metal [1] (yes the name kindda sucks, I know, but it is what it is) which is an evolution of my earlier attempt of reimplementing MPL. Not that gave up on the earlier idea, it just has grown far beyond that. [1]: https://brunocodutra.github.io/metal/concepts.html