Boost logo

Boost :

Subject: Re: [boost] [hana] Review
From: John Bytheway (jbytheway+boost_at_[hidden])
Date: 2015-06-24 21:52:49


On 2015-06-24 12:39, Louis Dionne wrote:
> John Bytheway <jbytheway+boost <at> gmail.com> writes:
>
>>
>> [...]
>> - What is your evaluation of the library's:
>> * Design
>>
>> The design seems reasonable, and I like the adherence to mathematical
>> concepts. The most difficult thing is getting the names right, and I
>> know there's been plenty of debate on that. The name that most concerns
>> me is Range, given that that term is already commonly used in Boost as a
>> concept with a completely different meaning (in the Boost.Range sense).
>
> Interval might be reasonable too?

Indeed, seems fine to me. I might be inclined to be more specific and
call it IntegerInterval, but that's not really necessary.

>> Mostly very good, but of course there is always room for improvement.
>> One particular thing I wanted to raise here is that I struggled to find
>> enough information about Hana-convertibility (i.e. using the 'to'
>> function). For example, I wondered if I could create a Tuple from a
>> Range, and it seems I can. Then I wondered whether I could create a
>> std::Array from a homogeneous Tuple, but it seems I cannot.
>
> A Tuple is a Sequence, and a Sequence can be created from any Foldable. Since
> a Range is Foldable, it works. However, a std::array is _not_ a Sequence.
>
>> How should I know these things?
>
> The Foldable -> Sequence conversion is documented in the reference of
> Foldable, here: http://ldionne.com/hana/structboost_1_1hana_1_1Foldable.html
> However, I agree that it could/should appear closer to the description of the
> `to` function. One problem is that a lot of types provide the `to` function,
> but I can't really describe all of them in the reference for `to`.
>
> Where should these conversions be documented to make it easier for users to
> find them?

Well, if they are documented in the source concept and the documentation
for 'to' states that that is where such conversions are documented, then
I think that's fine.

>> (This latter case of converting to an array is something I feel ought to
>> be supported for easing the boundary between runtime and compile-time
>> sequences)
>
> std::array is not "general" enough to allow construction from an arbitrary Hana
> Sequence. As you point out, it would only work for Sequences containing objects
> of a single type. However, this breaks the naturality of the `to` function.
> Of course, nothing prevents me from adding a conversion to std::arrays, but
> it wouldn't actually fit in Hana's mathematical framework.
>
> I know the above must seem quite fuzzy, so let me try to explain my point by
> considering the implementation of a `to<std::array>` conversion:
>
> namespace boost { namespace hana {
> template <typename S>
> struct to_impl<ext::std::Array, S, when<models<Sequence, S>()>> {
> template <typename Xs>
> static /*constexpr*/ auto apply(Xs&& xs) {
> using T = std::remove_reference_t<decltype(hana::head(xs))>;
> auto len = hana::length(xs);
> return hana::unpack(std::forward<Xs>(xs), [=](auto&& ...x) {
> return std::array<T, len>{{std::forward<decltype(x)>(x)...}};
> });
> }
> };
> }}
>
> See how we make an arbitrary choice to use the type of the first element of the
> sequence for `T`? This, and the fact that it will only work when the Sequence
> happens to contain elements of a single type, are what breaks naturality.

I understand the concern.

FWIW, the specific use case I was thinking of was being able to do
something like this for an arbitrary tuple t:

boost::algorithm::join(hana::to<Array>(hana::transform(t, to_string)), " ")

because boost::algorithm::join is expecting a runtime Range rather than
a compile-time one. Array seemed like the most likely candidate for
glueing these together. Do you have any alternative suggestions for
such situations?

>> [...]
>>
>> I went looking for some code of mine to try porting to Hana, and got
>> sidetracked by one difficulty. The first project I came across using
>> Boost.Fusion was passing a lot of fusion::vectors across function
>> interfaces, but the vector types were specific and the functions not
>> defined in headers. Hana's tuple cannot easily be used in this way
>> since the type is unspecified. I don't think this is a problem, because
>> (a) that code was just poorly written and ought instead to be using
>> adapted structs, which Hana does support, and (b) I can use Hana
>> algorithms with Fusion's tuples anyway.
>
> Technically, Hana's tuple has a specified type. That type is `hana::_tuple<...>`.
> The name will change to (probably) `hana::tuple<...>`.

I thought that tuple_t<...> might produce a different type of Tuple?

> It is true that most other
> data structures have unspecified types, but this is similar to how Fusion's
> vectors have numbered forms. I'm curious to know how the original code managed
> to pass Fusion vectors across interfaces? Did it make sure to only use the
> non-numbered fusion::vector<...> form, or something else?

Indeed, it only used the non-numbered versions. There was one part of
the code implementing some generic optimization which returned a
fusion::vector of parameter choices, and then elsewhere this was being
used in a specific case where the number and type of parameters was
known, and the resulting parameter vector was just passed around as-is
rather than converting it to a more meaningful type.

John


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