Boost logo

Boost :

Subject: Re: [boost] [Hana] Informal review request
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2015-03-07 06:32:17


Le 05/03/15 15:41, Louis Dionne a écrit :
> Dear Boost,
>
> As some may be aware of, I am currently working on a metaprogramming library
> called Hana, with the intention of proposing it for inclusion in Boost. The
> purpose of that library is to act as a toolbox for expressing computations
> on both types (like the MPL) and heterogeneous values (like Fusion). The
> library is built around C++14 idioms and implementation techniques to
> maximize expressiveness and performance.
Hi and thanks in advance for your work.
> I am now requesting feedback from the community, with the intention of asking
> for a formal review in the next months. A similar review was asked for in last
> August. The library has undergone several modifications since then, both to
> address issues raised during the review and for general improvement. Here are
> some issues that were raised during the review and addressed:
>
> - Usage of names and terms unknown to C++ programmers: Efforts were made to
> make this better, and several functions were renamed (`fmap` is now
> `transform`). When possible, the documentation also uses terms more
> familiar to C++ programmers, like concept instead of "type class".
I'm not sure the use of the term "concept" instead of "type class" is
appropriated (given that the C++ standard is defining concepts in a
different way). Hana "type class" is based, as Concept C++0x, on
signatures. An instance "type" of a "type class" needs a mapping of the
signature. I can live with the term TypeClass. Nevertheless if you don't
want to use it I will suggest you the terms "MappedConcept" or
"SignaturedConcept" instead of "Concept".
>
> - The order of the arguments to some algorithms was unfortunate for C++. It
> was consistent with Haskell, but it turned out to be cumbersome in C++.
Just for curiosity, could you give some examples of these changes and
why it was cumbersome?
> This is changed in most places.
>
> - Inability to easily implement individual algorithms: This is fixed, and
> algorithms are now standalone structures using tag-dispatching, almost
> exactly as in Fusion.
Just for curiosity, could you give some examples of these changes and
why it was difficult before the changes?
>
> - Lack of a good introductory tutorial: A lot of work has gone into improving
> both the tutorial and the reference documentation.

I appreciate what has been done already to improve the tutorial. Next
follows some comments about the design.

DataTypes and TypeClasses
----------------------
I appreciate what has been done already. I have some trouble with the
"datatype" use. If I understand it correctly, the type you map to a
"type class" is not the type itself but its datatype (which can be the
same).

In Haskell, type classes can be universally quantified or not. E.g. the
"type class" Eq is not universally quantified

class Eq a
`(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool

while the "type class" Functor it is universally quantified

class Functor f where
   fmap :: (a -> b) -> f a -> f b

That means that the instance mapping for Eq is from types (*) and the
instance mapping for Functor is for type constructors having one
parameter (* ->*).

Let me show the instance mapping for Either in Haskell

(Eq a, Eq b) => Eq (Either a b)

Functor (Either a)

Note the difference. In the first case the instance is Either a b. In
the second it is Either a.

I don't see this nuance in your library. The datatype of
left<A>/right<B> is Either, and the instance of Comparable and Functor
is always Either. BTW, I'm missing a type either<A,B> see below

I'm wondering if the library shouldn't make this difference and make
either<A,B> be an instance of Comparable and either<A,_> be an instance
of Functor, where either<A,_> stands for the universal type constructor
having a parameter.

Compile-time error reporting
--------------------

I would expect that the library provide some king of "TypeClass" check
use (As Eric's Range library does with Concepts) so that the compile
time errors are more explicit.

Unnamed data types
-----------------
I'm missing, between other, the concrete types _either<A,B> and
_maybe<T>, as we have _pair<A,B>. How the user can declare a structure
having data members with these data types?

About a pure type meta programming sub-library Hana/Meta
----------------------------------------------------

While I agree that it is good to be able to define the algorithms only
once for types and values, I find the syntax cumbersome when the user
wants only to work at the meta-programming level.

I wonder if the library shouldn't contain a sublibrary Hana/Meta that
defines in a meta namespace all the algorithms/types that work directly
on types and integral constants.

Instead of defining a hana::tuple_t, I suggest to define it in
meta::tuple that works only with types and a meta::transform that works
only on types.

This will allow to write ([1])

static_assert(
     meta::transform<meta:: tuple<int, char const, void>,
std::add_pointer>{} ==
     meta::tuple<int*, char const*, void*>{}
, "");

instead of

static_assert(
     hana::transform(hana::tuple_t<int, char const, void>,
hana::metafunction<std::add_pointer>) ==
     hana::tuple_t<int*, char const*, void*>
, "");

The definition of meta::transform will just do the steps 2 and 3 of the
process you describe:

 1. Wrap the types with |type<...>| so they become values
 2. Apply whatever type transformation |F| by using |metafunction<F>|
 3. Unwrap the result with |decltype(...)::type|

namespace meta {
   template <class Tuple, class F>
   using transform = |decltype(|hana::transform(Tuple{},
||hana::metafunction<F>))::type
}

An additional advantage of having this Meta library is that it can be
defined using just a C++11 compiler, as it is done in Eric's Meta library.

Best,
Vicente

[1] the name could be also meta::list.


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