|
Boost : |
Subject: Re: [boost] Reimplementation of the MPL for C++11
From: Abel Sinkovics (abel_at_[hidden])
Date: 2013-10-20 04:06:47
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk