[boost] [hana] Review

147 views
Skip to first unread message

edo...@fausse.info

unread,
Jun 15, 2015, 3:01:14 PM6/15/15
to bo...@lists.boost.org
Dear all,

Please find attached my review of Hana.

> - Whether you believe the library should be accepted into Boost
>   * Conditions for acceptance

Definitely yes. I just have a very minor remark considering the documentation.

> - Your name

Edouard Alligand

> - Your knowledge of the problem domain.

I have been writing C++ professionally for 15 years and done a lot of TMP for many software project, for things such as compile-time introspection for serialization, enhanced checks at compile-time to improve correctness and compile-time pre-computations. I've done that with Boost.MPL, Boost.Fusion and some custom MPL.

> You are strongly encouraged to also provide additional information:
> - What is your evaluation of the library's:
>   * Design

I am very much impressed by the design of Hana and the cleverness of the usage of C++ 14 lambdas.

>   * Implementation

As far as I can judge it is very well implemented.

>   * Documentation

I think writing "using namespace boost::hana" for the documentation is confusion. I know it might be nit-picking, but I think the example is easier to understand when you read

struct Fish { std::string name; };
struct Cat { std::string name; };
struct Dog { std::string name; };
auto animals = boost::hana::make_tuple(Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"});

instead of

struct Fish { std::string name; };
struct Cat { std::string name; };
struct Dog { std::string name; };
auto animals = make_tuple(Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"});

Because if you read diagonally (and let's be realistic, we all read diagonally documentation) you might miss what is going on. At least some namespace alias would be helpful. I personally think redundancy is good in documentations.

>   * Tests

There is a satisfactory number of tests and the developer does continuous integration. The developer tests on several compiler versions at every change which is a must for a MPL.

>   * Usefulness

Boost.Hana is extremely useful, especially the compile-time introspection it adds. It uses macros but as long as the language doesn't provide features to do compile-time introspection, there is no way around this (that I can think of)

It has a lot of algorithms out of the box (at least I couldn't find one I would need that was missing). I like the compile-time arithmetic part of the library and find it very convenient.

I'm a big fan of Boost.Fusion and I use Boost.MPL a lot. Hana replaces both libraries and compiles faster at the cost of requiring recent compilers. It is, to me, a very acceptable tradeoff.

> - Did you attempt to use the library? If so:
>   * Which compiler(s)

Clang 3.5 on FreeBSD 10.1 and libc++

>   * What was the experience? Any problems?

The only problem I have with Hana is that it doesn't work with Visual Studio. The lack of VS is the only reason why we didn't adopt Hana on our product. Nevertheless, I don't think it a showstopper. Hana is an advanced MPL and the problem will solve by itself with time. It works, in my opinion, on a sufficient number on platforms at the moment to be accepted into Boost.

> - How much effort did you put into your evaluation of the review?

I ran by the examples again as I would if I were trying the library for the first time. I have been following Boost.Hana since Louis' presentation at last year cppcon in Bellevue, Wa.

Kind regards.

--Edouard


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Louis Dionne

unread,
Jun 16, 2015, 9:59:50 AM6/16/15
to bo...@lists.boost.org
edouard <at> fausse.info <edouard <at> fausse.info> writes:

>
> [...]


>
> >   * Documentation
>
> I think writing "using namespace boost::hana" for the documentation is
> confusion. I know it might be nit-picking, but I think the example is
> easier to understand when you read
>

> [...]


>
> Because if you read diagonally (and let's be realistic, we all read
> diagonally documentation) you might miss what is going on. At least
> some namespace alias would be helpful. I personally think redundancy
> is good in documentations.

Good suggestion. I think a `namespace hana = boost::hana` alias would be
better than fully qualifying all the names. Added this issue [1].


>
> [...]


>
>
> >   * What was the experience? Any problems?
>
> The only problem I have with Hana is that it doesn't work with Visual
> Studio. The lack of VS is the only reason why we didn't adopt Hana on
> our product. Nevertheless, I don't think it a showstopper. Hana is an
> advanced MPL and the problem will solve by itself with time. It works,
> in my opinion, on a sufficient number on platforms at the moment to be
> accepted into Boost.

I think acceptance into boost and more wide usage of the library might also
push compiler vendors to (properly) support C++14 faster. That's sort of a
chicken-and-egg problem; if no one uses advanced features, vendors don't
have incentives to implement them and they also can't fix their bugs. On
the other hand, once all these features are available and bugfree, users
will use them.


> > - How much effort did you put into your evaluation of the review?
>
> I ran by the examples again as I would if I were trying the library for
> the first time. I have been following Boost.Hana since Louis' presentation
> at last year cppcon in Bellevue, Wa.

Thanks a lot for your review, Edouard!

Regards,
Louis

[1]: https://github.com/ldionne/hana/issues/126

Roland Bock

unread,
Jun 20, 2015, 3:00:58 PM6/20/15
to bo...@lists.boost.org
Hi,

Here are my review results:

- Whether you believe the library should be accepted into Boost
Yes.

- Your name
Roland Bock

- Your knowledge of the problem domain.
On the one hand, I do believe to have some knowledge in TMP, being the author of sqlpp11. I have made some minor contributions to early versions of Hana, discussing implementations of type sets and all/any/none. I experimented with the MPL for quite some time before the advent of C++11...

On the other hand, I am almost totally blank when it comes to Haskell or Fusion.


- What is your evaluation of the library's:
* Design
Awesome. Using template variables to turn types into objects and then treating types and values the same way in most places is very cool.

* Implementation
I haven't spent too much time on the implementation. I read code around hana::string and hana::all. It was nicely structured and quite readable.

* Documentation
Impressive already. With all the input from the reviews coming in, it will become even better.

I found navigation/searching a bit awkward sometimes. Personally, I would like more cross links/tables. E.g. functions working with Set (Louis already created an issue on github for this).

* Tests
To be honest, I did not look at them.

* Usefulness
We'll see what comes out of it. Which libraries are actually going to use Hana. I'll give it a try with sqlpp11. As others have stated, it might be a bit too much even.

BUT, regardless of how many projects will actually use it, Hana will force some compiler teams to go to great lengths to be able to compile the library. It might also become a benchmark in terms of compile time and the number of generated instructions.

Also, Hana contains a wealth of design ideas, tricks and knowledge for anybody who needs to solve a particular compile time problem. I am sure that many library authors and other developers will benefit from this Hana being available, maintained and developed within Boost.

And Hana has minimal dependencies (just a handful of headers from the standard library). Thus Hana might help to change the impression that many people have of Boost (coming from many established, older Boost libraries): Awesomely cool stuff, but dependencies from all nine levels of hell (aka, you can look, but you better not touch).

To sum it up: Usefulness? Very!

- Did you attempt to use the library? If so:
* Which compiler(s)?
clang-3.5.1

* What was the experience? Any problems?
As described in an earlier mail:
- I tried to use Hana's string UDL (the gcc/clang hack) but failed. Hana is not to blame here, it is rather because of shortcomings in the C++ core language.
- I thought about using Hana's all/any/none, but my own versions were proven (by Louis himself) to be outstandingly fast, so no reason to switch
- I thought of switching to Hana's compile time sets, but that seemed like a tough thing to do considering that I am using type sets and Hana is using value sets. Louis showed samples from Zach Laine which would make the transition easier. Actually, something like this should be part of the documentation. Maybe it might make sense to have a collection of migration examples (before/after code)?

That might not sound very successful, but I think it was: While researching how I could achieve my goals I learned a lot about the library.

- How much effort did you put into your evaluation of the review?
Several hours of reading and some tests in combination with sqlpp11.

Remark on compilers:
There was some argument as to whether Boost could contain a library that can only be compiled by one compiler (actually, maybe two in this case). My personal opinion is: Yes, Boost could and should do that if the library complies with a modern version of the C++ standard. Compiler teams take pride in being able to compile boost. If they cannot compile a Boost library, they will try to accomplish that ASAP. This is going to help everyone. It is good to have libraries in Boost that challenge compilers even to the point of breaking one or the other. Trying to work around compiler bugs does not seem right for new libraries.


Thanks to Louis for his library and to Glen for managing the review!

Best,

Roland

Louis Dionne

unread,
Jun 20, 2015, 5:25:18 PM6/20/15
to bo...@lists.boost.org
Roland Bock <rbock <at> eudoxos.de> writes:

>
> [...]
>
> - I thought of switching to Hana's compile time sets, but that seemed like
> a tough thing to do considering that I am using type sets and Hana is
> using value sets. Louis showed samples from Zach Laine which would make
> the transition easier. Actually, something like this should be part of
> the documentation. Maybe it might make sense to have a collection of
> migration examples (before/after code)?

That's a good idea. It's not a small amount of work, but it's worthy of an
issue [1].


> [...]
>
> Thanks to Louis for his library and to Glen for managing the review!

Thanks for your review, Roland. Also, thanks a lot for sharing some TMP
tricks on this list; they were both useful and also a nice inspiration
for even more tricks :-).

Regards,
Louis

[1]: https://github.com/ldionne/hana/issues/142

John Bytheway

unread,
Jun 23, 2015, 9:03:45 AM6/23/15
to bo...@lists.boost.org
This is a somewhat perfunctory review of Hana, because I wanted to get
something in before the end of the review period.

I have submitted a few issues on GitHub, for minor things that need not
be repeated here. Below are the things I found that might warrant more
discussion.

- Whether you believe the library should be accepted into Boost
* Conditions for acceptance

Yes it should. No specific conditions.

- Your name

John Bytheway

- Your knowledge of the problem domain.

User of TMP for years. Once wrote a source-to-source translator to help
me write MPL programs because it was prohibitively difficult to write
them correctly by hand.

- 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).

* Implementation

Did not look.

* Documentation

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. How should
I know these things?

(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)

* Tests

Did not look.

* Usefulness

Very, although not useful for me personally until I decide to bite the
ABI-breaking bullet and recompile all my code in gcc 5.x with the new
libstdc++.

The biggest risk I see is MSVC support. Microsoft seem to be much more
standards-gung-ho than they once were, so I hope it won't take too much
longer before we see support. But I do encourage Louis to be wary of
taking advantage of any new language features (e.g. a potential change
in C++17 lambdas-in-unevaluated-contexts rules, or the compiler
extension for compile-time string literals) lest it delay MSVC support.

- Did you attempt to use the library? If so:
* Which compiler(s)

clang 3.6.1

* What was the experience? Any problems?

I played around a bit, mostly with a view to finding out how bad the
compiler errors are when things go wrong. The results were promising.

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.

- How much effort did you put into your evaluation of the review?

A few hours reading and playing.



Thanks very much to Louis for his effort. I look forward to being able
to use Hana in the not-too-distant future, and I'll make GitHub issues
for any more things I discover in my testing.

John

Louis Dionne

unread,
Jun 24, 2015, 12:40:13 PM6/24/15
to bo...@lists.boost.org
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?


> * Implementation
>
> Did not look.
>
> * Documentation
>
> 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?


> (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 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<...>`. 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?


> - How much effort did you put into your evaluation of the review?
>
> A few hours reading and playing.
>
> Thanks very much to Louis for his effort. I look forward to being able
> to use Hana in the not-too-distant future, and I'll make GitHub issues
> for any more things I discover in my testing.
>
> John

Thanks a lot for your review, John.

Regards,
Louis

Vicente J. Botet Escriba

unread,
Jun 24, 2015, 1:23:16 PM6/24/15
to bo...@lists.boost.org
Le 24/06/15 18:39, Louis Dionne a écrit :
> 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?
>
>
>> * Implementation
>>
>> Did not look.
>>
>> * Documentation
>>
>> 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.

Couldn't std::array<T,0> be considered the empty Array and so Array
could be considered a homogeneous 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?
I would put the To function on the Source class it it s a concrete type.
Otherwise on the Target class.
It could be added on a see also section for the other class or concept.

>> (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.
Why not request that the sequence is homogeneous?

Vicente

John Bytheway

unread,
Jun 24, 2015, 9:53:33 PM6/24/15
to bo...@lists.boost.org
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

Louis Dionne

unread,
Jun 25, 2015, 6:03:36 PM6/25/15
to bo...@lists.boost.org
Vicente J. Botet Escriba <vicente.botet <at> wanadoo.fr> writes:

>
> Le 24/06/15 18:39, Louis Dionne a écrit :
> > John Bytheway <jbytheway+boost <at> gmail.com> writes:
> >
> >> [...]
> >>

> >> 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.
>
> Couldn't std::array<T,0> be considered the empty Array and so Array
> could be considered a homogeneous sequence?

The problem is that a homogeneous sequence (in Hana's mathematical universe)
is a sequence whose tags are homogeneous. Hence, a tuple containing
IntegralConstant<int> objects only is a homogeneous sequence for Hana's
concepts. Hence, a std::array is not powerful enough to hold Hana-homogeneous
data. Indeed, the following is Hana-homogeneous but not homogeneous in the
usual C++ sense:

auto xs = make_tuple(int_<1>, int_<2>, int_<3>);

It is Hana-homogeneous because all the int_s have the IntegralConstant<int>
tag, but it is not C++-homogeneous because they all have different C++ types.
Again, the concern here is being correct mathematically, but there's no other
technical reason why this can't be done. Ideally, I'd like to be mathematically
correct while also providing this functionality, or similar.


> > [...]


> >
> > 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.
> Why not request that the sequence is homogeneous?

My answer to your other question above should also answer this one. If not,
let me know and I'll gladly clarify.

Regards,
Louis

Louis Dionne

unread,
Jun 27, 2015, 10:48:04 AM6/27/15
to bo...@lists.boost.org
> On 2015-06-24 12:39, Louis Dionne wrote:
>
> > [...]
> > 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.

Good idea. I added this to the documentation of `to`.


> [...]
>
> 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 don't know how generally this applies, but I would suggest the following
for your precise use case:

boost::algorithm::join(hana::unpack(t, [](auto&& ...x) {
return std::array<std::string, sizeof...(x)>{{
to_string(std::forward<decltype(x)>(x))...
}};
}), " ");

In addition, this will be lightning fast because unpacking a tuple is very
cheap and you do not require any layer between your call to to_string and
the creation of your array, so you minimize the number of functions that are
instantiated.


> >> [...]
> >>
> >> 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?

That is correct, and my comment was unclear. `make_tuple(...)` has a
specified
type, but `tuple_t<...>` does not.


> > 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.

Ok. Might this qualify as a borderline usage of Fusion's implementation
details?

Regards,
Louis




--
View this message in context: http://boost.2283326.n4.nabble.com/hana-Review-tp4677475p4677597.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

John Bytheway

unread,
Jun 28, 2015, 1:37:21 PM6/28/15
to bo...@lists.boost.org
On 2015-06-27 10:25, Louis Dionne wrote:
>> 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 don't know how generally this applies, but I would suggest the following
> for your precise use case:
>
> boost::algorithm::join(hana::unpack(t, [](auto&& ...x) {
> return std::array<std::string, sizeof...(x)>{{
> to_string(std::forward<decltype(x)>(x))...
> }};
> }), " ");
>
> In addition, this will be lightning fast because unpacking a tuple is very
> cheap and you do not require any layer between your call to to_string and
> the creation of your array, so you minimize the number of functions that are
> instantiated.

Makes sense. And I guess I can write a function converting to arrays
fairly easily if I want one.

>>> 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.
>
> Ok. Might this qualify as a borderline usage of Fusion's implementation
> details?

I don't think so. I believe all Fusion sequences are assignable and
constructible from each other (when they have the same number of and
assignable elements), so even if a pass a vector2<double, double> to a
function
expecting a vector<double, double> it will work fine.

This mutual assignability is very useful in certain cases; for example
it makes it easy to use adapted structs in Boost.Spirit to store the
result of parsing.

John
Reply all
Reply to author
Forward
0 new messages