Vicente J. Botet Escriba
writes: Dear Boost community,
The formal review of Louis Dionne's Hana library starts Monday, 10th June and ends on 24th June.
Hana is a header-only library for C++ metaprogramming that provides facilities for computations on both types and values. It provides a superset of the functionality provided by Boost.MPL and Boost.Fusion but with more expressiveness, faster compilation times, and faster (or equal) run times. <snip> We encourage your participation in this review. At a minimum, kindly state: Here is my mini review. I have created some issues on github. My vote is not subject to the result of any of them. Thanks for your review, Vicente. Also, thanks a lot for the issues on GitHub;
Le 05/06/15 21:18, Glen Fernandes a écrit : these will definitely contribute to improving the quality of the library.
- Whether you believe the library should be accepted into Boost Yes, yes and yes. I consider Boost.Hana must be accepted into Boost. - Your name Vicente J. Botet Escriba - Your knowledge of the problem domain. A good knowledge and I have learn a lot more with the work of Louis in Hana. You are strongly encouraged to also provide additional information: - What is your evaluation of the library's: * Design Brilliant, awesome. Seen types as values is a revolutionary design. Thanks Louis. For full disclosure, I must admit that the idea of seeing types as values was first brought up by Matt Calabrese and Zach Laine at BoostCon 2012 [1]. I discovered the thing on my own in 2014 [2], but they definitely were there first. Then thanks Louis to make use of this idiom on your meta-programming
Le 15/06/15 22:39, Louis Dionne a écrit : library. And of course thanks to Matt and Zach. I will take a look at the presentation (I believe that I was there :( )
I liked the way the Haskel concepts have been adapted to C++14.
In previous version of the library (I don't know when this has been changed), I liked * type classes, * the instantiation either directly or when the type is an instance of a type class (using the second parameter). If you are referring to automatically-defined models, this is still possible. For example, the model of Monoid is automatically provided for any Constant containing something that's a Monoid too:
template <typename C> struct plus_impl
() && models () >> { // implementation of plus() }; template <typename C> struct zero_impl
() && models () >> { // implementation of zero<> }; The difference with the previous design, IIRC, is that in order to define a model of Monoid, you used to write something like
template <typename C> struct Monoid::instance
() && models () >> { // implementation of plus() and zero<> }; Both are essentially equivalent, except that you can now define individual algorithms more easily.
Yes, it is still possible, but you need more. With the previous design you you could design an mcd that forward to the current design.
* the minimum definition set and how to inherit from them. * The split concepts and data_types to make it more evident the distinction.
All this has now disappeared, surely as requested in this ML :(.
Things that I like less are
* the data_type (tag) concept. IMO, what is behind is a type constructor. A type constructor is a class that has a nested alias template apply to build new types. A class template can also be seen as a type constructor by lifting it. For others reading this, see this issue [3] for the ongoing discussion about this.
* the fact that the result type of a lot of functions is not a concrete type or is not defined. This is a real difficulty. I could provide types, but then they wouldn't be useful at all in most cases, and they would often be straight up misleading. For the reference of others reading this, please see this issue [4].
* the fact that the interface is not typed, the use of auto and lambdas everywhere is less informative that a typed interface. That is a documentation issue, right? I could devise a convention where the concepts expected from each argument is used in the signature, something like this:
auto fold_left = [](Foldable&& xs, auto&& state, auto&& function) { // ... };
But then I would still need to explain the signature in prose, i.e. the fact that the function must take a state and an element from the Foldable, and so on. Anyway, I'm open to suggestions, but heterogeneous programming definitely brings different documentation challenges from usual generic programming.
Agreed that heterogeneous types add some difficulty.
* the Signature as an alternative way to define the interface should be documented. The usage of the signature to document the interface is now explained at the end of the tutorial, in a section explaining how to use the reference documentation. This is issue [5].
Great.
I would find more useful to define the signature before the description. So you would prefer the description in words to come after the signature in semi-formal math language? I guess I could try that out and see how it looks like, but I am under the impression that most people would prefer it the other way around. Created issue [6] to remember to try it out.
* This is a library with a lot of Concepts. It is not easy to find the correct name for each of them and each of the functions in the C++ world when the concepts come from another language with different history. There are some names that I don't like, but I recognize that finding a coherent set of names is not easy.
* the fact that all the functions are in the same namespace. This imply that we need to find a different name for each function. Making use of namespaces for each concept add a freedom degree. One of my fears is that this would make the library much more complicated, especially for new users. What would happen if you had to prefix each algorithm with the name of the concept that defines it? I know I would sometimes ask myself "hey, what concept defines this?", so I can only imagine the worse for other users. I see this differently. It will force the user to ask himself, what exact function he is using.
My preference so far has been to deal with this missing degree of liberty by selecting names that do not clash. It is sometimes a bit annoying, but I think the resulting simplicity is worth it. Currently you are free to use any names in boost::hana, but how would you name them if you were writing a proposal for the C++ standard? We will have Range-V3 one day and others that make use of similar names. Associating the names to the concepts allow to get rid of all these
I find clearer when the description talks of a function I know the signature it has. possible clashes.
* The functional part has disappeared as there were some overlapping with Boost.Fit (We need now Boost.Fit). Technically, it's still part of Hana. It was hidden in the Details section of the documentation to give me the liberty to switch to Fit in the future, but I wouldn't consider its functionality gone for good.
* the instantiation either directly or when the type is an instance of a type class (using the second parameter). This was also listed in the things you liked, so I guess you have a love and hate relationship with this feature :-).
:( I guess that I mean here that this has disappeared at the Concept level.
I'm not yet clear about * the fact that Hana has reimplemented part of the standard to avoid dependencies and improve performances. IMHO, this is not the C++ way, I have removed Hana's reimplementation of
on the develop branch. Given the size the library has grown to (> 25 kLOCs), I don't think it was justified anymore not to use , which is usually around 3 kLOCs. At first, when Hana was really small, I think it was justified.
Ok.
* Implementation
I used to inspect the old version. I have less inspected the current one.
I find it quite clear and elegant even if I prefer the architecture of the old version.
* Documentation
Very good tutorial.
The documentation would improve a lot with a better design rationale section. * What a Concept is and how the map is done. This will be handled by the section on "Creating new concepts" in the "Extending the library" section (which is now "Hana's core" on develop).
Great.
* What a Tag/datatype is, why do we need it, alternatives, and how all this works. Tags are now explained in a new section about Tags on the develop branch.
Great.
* Naming and order of parameters I just added a rationale for what drives my name choices and the order of parameters.
Great.
* Why and when free functions or member functions are used. I'm not sure whether it is Hana's job to explain why free functions are better than member functions for generic programming. I don't know, but I feel like anyone reading Hana's tutorial would know the answer :-). It seems that you use free functions everywhere except when you can not. Am I wrong?
The reference documentation is a little bit confusing for some one used to the C++ standard way. * The terms Concept/Superclass/Methods, ... Now using Concept/"Refined Concept"/Functions. Thanks.
* A more formal definition of the mappings from concrete type to Concepts and the Super classes
Maybe this is enough for Boost, but I would like to see a more C++ standard like documentation. I'm not sure I understand what you mean by a more formal definition of the mapping from concrete type to concepts. Do you mean that the requirements of a concept should be defined more formally? I would like a description that defines what expressions are valid given some constraints on other expressions.
* Tests
Not inspected in depth, but it seems well covered.
* Usefulness
Very useful.
Even if I have not used it directly, I have taken a lot of ideas from his design. If the announced performances are there, it is clear that Boost.Hana will be used more a more by those that can use a C++14 compiler. I'll hope adding a dependency on the C++ standard library will not degrade the performance so much. Adding a dependency on the standard library (basically the
and the <utility> headers) do not seem to have a large impact on compile-times right now. Actually, it might be worse for micro-benchmarks because we're pulling slightly more stuff, but for actual code bases it's going to be better because we're reusing , which everyone includes anyway. Great. - Did you attempt to use the library? If so: No yet.
I will do it as soon as I install the good compiler version. You can try it online at [7].
I will do. I would like to see how something like the metaparse library or (http://blog.mattbierner.com/stupid-template-tricks-pride-and-parser-combinat...) becomes while using Hana interface.
* Which compiler(s)? * What was the experience? Any problems? - How much effort did you put into your evaluation of the review?
Thanks again Louis for this wonderful library. I would like to see in Boost a similar functional library but this time for run-time types. Thanks for the review.
Vicente