On 5/20/14, 1:28 AM, Louis Dionne wrote:
Joel de Guzman
writes: On 5/19/14, 4:41 AM, Louis Dionne wrote:
After discussing the issue several times during the week, I (and others) think it might be possible to merge Fusion and the MPL into a single library. I am currently trying to write a library that does that. Since this constitutes a large reorientation, I created a new repository which is available at [2]. Those with interest should consider subscribing to the repository to be updated as I make progress.
Been there tried that...
This has been proposed several times in the past. I reiterate my position: MPL and Fusion are different beasts and it is not good for both to be merged (if it is at all possible). MPL does not have the runtime components that Fusion needs and Fusion has runtime components that MPL *does not* need.
This is true, the MPL does not _need_ a runtime component. Adding one should be harmless if done correctly. There might be a performance penalty though, but I'll benchmark that eventually.
Also, because of the runtime aspects of Fusion, the semantics of algorithms do not make sense in MPL. Take the any algo for example:
Note that odd in that example is a runtime operation. How do you unite that? It works only with fusion sequences (with values) and not with MPL sequences (with types). In MPL, that would be a type-only predicate.
As of writing this, here is what I am able to do [1]:
Purely runtime predicate ------------------------ struct odd { template <typename T> bool operator()(T t) const { return t % 2; } };
assert(any(odd{}, list(1, 2))); assert(!any(odd{}, list(2, 4)));
Constexpr predicate ------------------- struct odd { template <typename T> constexpr bool operator()(T t) const { return t % 2; } };
static_assert(any(odd{}, list(1, 2)), ""); static_assert(!any(odd{}, list(2, 4)), "");
Type-only predicate ------------------- struct odd { template <typename T> constexpr auto operator()(T t) const { return t % int_<2>; } };
static_assert(std::is_same< decltype(any(odd{}, list(int_<1>, int_<2>))), Bool<true> >::value, "");
static_assert(std::is_same< decltype(any(odd{}, list(int_<2>, int_<4>))), Bool<false> >::value, "");
The trick for the type-only predicate is that there exists an overload
template
constexpr Int operator%(Int<i>, Int<j>) { return {}; } where Int<...> is the type of int_<...>. Since int_<...> is implicitly constexpr convertible to int, one can just write the predicate as
struct odd { template <typename T> constexpr auto operator()(T t) const { return t % int_<2>; } };
and use it in the three examples. So there is no code duplication and purely compile-time functions can now also be used as runtime or constexpr functions for free. This is a large gain IMO.
As far as I can see, everything that can be done with the MPL may also be done with a variation of this technique. For an example, see [2].
Amazing! Now that looks like a game changer. I think you are getting me convinced! I like it!
If you add values to MPL, it would be 1) unnecessarily more complex than it needs to be
I don't see why that should be, and my experience suggests something different. Could you please expand on this point and/or provide evidence backing this claim?
No. That was based on past experiences with pre C++11 compilers. If you can do this right with a reasonably small overhead and still support the most important use cases of Fusion, then I'm all for it.
and 2) the feature set would be comprised of very ugly mongrels.
Again, I don't see why that should be and my experience suggests that this is not the case.
Regards, Louis Dionne
[1]: https://github.com/ldionne/hana/blob/master/test/misc/fusion_any.cpp [2]: https://github.com/ldionne/hana/blob/master/test/type/mpl_equivalent.cpp
That is very nice, Louis! Let's see how this goes. Go for it! Regards, -- Joel de Guzman http://www.ciere.com http://boost-spirit.com http://www.cycfi.com/