Boost logo

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