Boost logo

Boost :

Subject: Re: [boost] [GSoC, MPL11] Community probe
From: Jonathan Wakely (jwakely.boost_at_[hidden])
Date: 2014-04-30 10:50:47


On 30 April 2014 15:03, Zach Laine wrote:
>
> Here are the metaprogramming capabilities I needed for my Fusion-like data
> structures:
>
> 1) compile-time type traits, as above
> 2) simple compile-time computation, as above
> 3) purely compile-time iteration over every element of a single list of
> types
> 4) purely compile-time iteration over every pair of elements in two lists
> of types (for zip-like operations, e.g. elementwise matrix products)
> 5) runtime iteration over every element of a single tuple
> 6) runtime iteration over every pair of elements in two tuples (again, for
> zip-like operations)
>
> For my purposes, operations performed at each iteration in 3 through 6
> above may sometimes require the index of the iteration. Again, this is
> probably atypical.
>
> 1 is covered nicely by existing traits, and 2 is covered by ad hoc
> application-specific code (I don't see how a library helps here).
>
> There are several solutions that work for at least one of 3-6:
>
> - Compile-time foldl(); I did mine as constexpr, simply for readability.
> - Runtime foldl().
> - Direct expansion of a template parameter pack; example:
>
> template <typename MatrixLHS, typename MatrixRHS, std::size_t ...I>
> auto element_prod_impl (
> MatrixLHS lhs,
> MatrixRHS rhs,
> std::index_sequence<I...>
> ) {
> return std::make_tuple(
> (tuple_access::get<I>(lhs) * tuple_access::get<I>(rhs))...
> );
> }
>
> (This produces the actual result of multiplying two matrices
> element-by-element (or at least the resulting matrix's internal tuple
> storage). I'm not really doing any metaprogramming here at all, and that's
> sort of the point.

I found your whole email very interesting, thanks for sharing your
experience, but I wanted to comment on the point above.

In some ways MPL is beautiful, for what it manages to do and the
design and ideas present in it, but syntactically it is hideous and
hairy.

I'm extremely pleased that the addition of two "small" features
(return type deduction and variadic templates, the latter enabling
tuples and index sequences) to the core C++ language enables you to
write code like that above, rather than jumping through complex hoops
with MPL. That's a real success story in my opinion.

> Any MPL successor should be as easy to use as the above
> was to write, or I'll always write the above instead.

I wholeheartedly agree. The MPL was necessary in the past because
recreating even small parts of that framework was a massive
undertaking. Now it's comparatively simple to do some things directly
(or with a small ad-hoc utility) rather than needing to leverage
chunks of the MPL. If MPL v2 isn't much easier to read and write than
MPL then it will be a wasted opportunity.

> I've been using these to write less code, if only a bit less.
>
> Instead of:
>
> template <typename Tuple>
> struct meta;
>
> template <typename ...T>
> struct meta<std::tuple<T...>>
> { using type = /*...*/; };
>
> I've been writing:
>
> template <typename ...T>
> constexpr auto meta (std::tuple<T...>)
> { return /*...*/; }
>
> ...and calling it as decltype(meta(std::tuple</*...*/>{})). This both
> eliminates the noise coming from having a base/specialization template pair
> instead of one template, and also removes the need for a *_t template alias
> and/or typename /*...*/::type.

Yes, I've found constexpr functions can greatly simplify some aspects
of metaprogramming, although so far a lot of it has been seeing what
other people are doing with them and I haven't quite got into the
habit of using them fully myself.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk