|
Boost : |
Subject: [boost] [yap] Review
From: P F (pfultz2_at_[hidden])
Date: 2018-02-12 22:15:23
- Whether you believe the library should be accepted into Boost
I think it should be Accepted.
- Your name
Paul Fultz II
- What is your evaluation of the library's:
The design is very nice and simple to follow. I have found Proto to be a little hard for me to grep, but this seems fairly simple to follow.
I think the transform -> evalute workflow is great. Also, with transforms being just function objects, it makes transformations very composable.
I think this library is very useful. I would love to use this for some projects at work, but the dependency on Hana prevents that(I need to support gcc 5 and MSVC). Looking at the codebase, it could easily be replaced with Boost.Fit(once its included in the release) in the future.
Of course, I dont expect a reimplementation without Hana as a condition for acceptance. However, I think Hana at least can be removed from the "interface". The expression elements could be expressed as a `std::tuple` and the placeholders could be a `std::integral_constant`. This should make it easier to use another backend without breaking API compatibility.
Some other notes:
- Couldn't the operator macros be provided as base classes? So instead of writing:
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr
{
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
// Member operator overloads for operator!().
BOOST_YAP_USER_UNARY_OPERATOR_MEMBER(logical_not, ::user_expr)
};
The user could write:
template <boost::yap::expr_kind Kind, typename Tuple>
struct user_expr : logical_not<::user_expr>
{
static const boost::yap::expr_kind kind = Kind;
Tuple elements;
};
You could also get rid of the need for `::user_expr` by just taking it as a type and using something similiar to `mp_transform` to change the parameters. Or even change `Kind` to be a type of `std::integral_constant<boost::yap::expr_kind, Kind>` so `mp_transform` could be used directly:
template <typename Kind, typename Tuple>
struct user_expr : logical_not<user_expr>
{
static const boost::yap::expr_kind kind = Kind{};
Tuple elements;
};
- The customization points seem unnecessary. Why wouldn't the user just use `transform`? Using `transform` also keeps the customizations local. Also, implicit transformations seems like it would lead to suprises(and not good suprises). Are those on the cutting block?
- It would be interesting to provide common transformations, like common subexpression elimination, or dead code elimination, but I guess that is beyond the scope of this library.
- The `op_string` function is missing the case for `expr_ref` and `terminal`. Also, the tests only check for plus.
- The `make_expr_from_tuple` does a move here:
auto make_expr_from_tuple (ExprTemplate<Kind, OldTuple> const & expr, NewTuple && tuple)
{ return ExprTemplate<Kind, NewTuple>{std::move(tuple)}; }
But maybe this should be using `std::forward`?
- Did you attempt to use the library? If so:
Yes, I ran it on clang 3.8 and gcc 7.
- How much effort did you put into your evaluation of the review?
Several hours
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk