
Hi, On 2013-10-18 20:07, Louis Dionne wrote:
Hi,
I am currently working on a reimplementation of the MPL for C++11. Although the library is not complete yet, I would like to gauge interest for the project from the Boost community.
I wanted to wait until I have resolved some core issues before posting here, but reading the [modularization] thread made it unbearable to wait any longer :-). The library is available on GitHub: github.com/ldionne/mpl11.
If some people happen to be interested by the project and would like to get involved, please get in touch with me.
I'm developing template metaprogramming libraries and I have built a "base" library (Metamonad) based on the functional nature of template metaprogramming. It is mostly an extension of the current Boost.MPL. It adds algebraic data-types, pattern matching, let expressions, exception handling, etc. I have looked at a few things in your mpl11 (sample programs would be useful). I have noticed the following: 1) I can see that you have this syntax for if_: if_<CONDITION, THEN>:: else_if<CONDITION, THEN>:: ... else<ELSE> which is I think a great DSL for the if structure. Can this be used in a lambda expression? For example: sort< vector<....>, lambda< if_<greater<_1, _2>, ...>:: else<...>
I have built a DSL similar to your if_ for exception handling in template metaprograms: try_<...> ::catch_<....> ::catch_<....> but I could not make it work with lambdas (and a number of things I have built using similar techniques). So I had to change it to: try_<...., catch_<....>, catch_<....>
There are a few things I would reconsider in a rewrite of MPL: 2) Metafunctions could support lazy evaluation. This makes it possible to use lazy evaluation strategy in metaprograms which makes the code easier to read. (Even for a factorial or Fibonacci there are huge differences) Currently MPL does not support this - for example the following works: boost::mpl::at_c< boost::mpl::push_front< boost::mpl::vector<int, double, char>, void
::type, 1 ::type
but the following does not: boost::mpl::at_c< boost::mpl::push_front< boost::mpl::vector<int, double, char>, void
, 1 ::type
The problem here is that at_c expects the caller to pass in push_front<...>::type instead of just push_front<...>. at_c could assume, that it has to use its argument's ::type instead of the argument directly. I have built a template called lazy<...> (see http://abel.web.elte.hu/mpllibs/metamonad/manual.html#lazy-metafunctions) as a workaround, but having the metafunctions of MPL supporting it would be more efficient. Also, I have reimplemented some of the things that are in Boost.MPL (eg. http://abel.web.elte.hu/mpllibs/metamonad/reference.html#pair, http://abel.web.elte.hu/mpllibs/metamonad/if_.html) in a way that they support lazy evaluation and use them instead of the original MPL versions. 3) Naming the lambda arguments _1, _2, ... has limitations. When you use lambda inside lambda, you can not refer to the arguments of the outer lambda from the inner one. I have built a lambda implementation where you can give the arguments names and use that instead of the MPL one. Here is an example for using it: using namespace mpllibs::metamonad; using namespace mpllibs::metamonad::name; boost::mpl::sort< boost::mpl::vector_c<int, 0, 3, 9, 4, 7, 2, 1, 8, 5, 6>, lambda_c<x, y, boost::mpl::greater<x, y>>
::type
You can read about my lambda implementation here: http://abel.web.elte.hu/mpllibs/metamonad/manual.html#lambda-expressions It is based on syntaxes and variables, which are described earlier on that page. This problem can also be solved by using De Brujin indices, but I find using names more readable so I decided to use this in my lambdas. Regards, Ábel