Boost logo

Boost :

Subject: Re: [boost] [Hana] Announcing Hana's formal review next week (June 10th)
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2015-06-16 02:58:50


Le 15/06/15 22:39, Louis Dionne a écrit :
> Vicente J. Botet Escriba <vicente.botet <at> wanadoo.fr> writes:
>
>> Le 05/06/15 21:18, Glen Fernandes a écrit :
>>> 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;
> 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
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<C, C, when<
> models<Constant, C>() &&
> models<Monoid, typename C::value_type>()
> >> {
> // implementation of plus()
> };
>
> template <typename C>
> struct zero_impl<C, when<
> models<Constant, C>() &&
> models<Monoid, typename C::value_type>()
> >> {
> // 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<C, C, when<
> models<Constant, C>() &&
> models<Monoid, typename C::value_type>()
> >> {
> // 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.
>
I find clearer when the description talks of a function I know the
signature it has.
>> * 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
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 <type_traits> 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 <type_traits>, 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 <type_traits> 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 <type_traits>, 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-combinators-part-one/)
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


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