pfultz2
Awesome library! Here are some of my thoughts on the library.
It seems like you are bringing haskell to C++. However, in the past, functional libraies seem to struggle with acceptance in boost. It seems like it would be nicer to name and organize things in a way that is familiar to C++ programmers. One of the things that helped make it easy for me when I firsted learned Boost.MPL, was it was built around the STL interface. I understand in Boost.Hana, you don't use iterators for performance,
That is slightly inacurate. I don't use iterators because other abstractions provide much more expressiveness and are much more general than iterators. Since performance is not an argument in favor of iterators in our case (as you rightly observe), they are not used. The #1 reason is expressiveness.
but it still could be organized in a way that is more familiar to C++ programmers (Some places I've worked, there was resistance to even using Boost.Fusion, which is built around familiar C++ interfaces. Imagine if I tried to introduce Boost.Hana.)
Hana is fundamentally functional, it uses rather abstract concepts and that's what makes it so powerful. Truth is, "Sequence" and "Container" concepts are easy to understand but they only get you so far; they are not general enough to be used as building blocks. I did try using both.
Here's a few list of names off the top of my head that could use more C++-like names:
foldl = fold foldr = reverse_fold fmap = transform cons = push_front scons = push_back datatype = tag,tag_of head = front last = back typeclass = concept
I agree that using more C++ish names could make it more tempting for people to adopt the library. I'll think about providing aliases.
Also, most C++ programmers are used to seeing libraries divided into containers and algorithms, whereas Boost.Hana seemed to be built around haskell-like interfaces.
Hana is actually built around concepts (type classes) and models of those concepts (data types). Apart from the names, which I agree could have been chosen differently, it's the same "design paradigm" as usual generic C++ libraries.
As C++ programmers, its difficult to find where to look for functionality.
Improving the documentation should make it easier for people to find the functionality they want.
Ideally, it would be nice to start with simple concepts, such as iteration, and then have algorithms built on top of that.
I'm not sure what you mean by that. Do you mean change the structure of type classes, or how they are introduced?
And then have a mechanism to overload algorithms to improve the performance for certain sequences(for example `mpl::vector` algorithms could be specialized to improve compile time performance).
The current type class system allows you to do just that, and it's used extensively in the implementation. This is explained in the tutorial section on type classes, when I give an example with `std::string` specializing `Printable` to make `to_string` more efficient. Should I clarify this section?
It seems like you can overload the algorithms in your library, but its spread across different typeclasses. And then the `List` typeclass has a bunch of algorithms in them. Since, `List` is heavy, I can't split the specializations of these algorithms across several header files, for example. It would be better to have smaller and simpler concepts.
There are two things here. First, the decision not to split the library into a thousand headers was considered a feature, because it meant that you did not need to include countless headers to get some functionality. Since the library is very lightweight, it does not cause a compile-time performance problem to include the whole list.hpp header. Second, I agree that the List type class is heavy, but that's because it's more like a data type really. The only reason I made it a type class is because I wanted to give `fusion::vector`, `std::tuple` and friends the same methods as `hana::list`, for free. The laws of List force every instance to be isomorphic to `hana::list`, so there is no reason why you would want to instantiate it. Basically, if you're instantiating List, you've just created a new container that does _exactly_ the same as `hana::list`, and you would be better off using this one in that case. This is why I don't see `List` being such a large type class as a big problem.
However, the specializations of these concepts should be for advance use of the libraries. It should start with some simple concepts to get people to start using the library, and then if someone wants to create an optimized `reverse_fold`, they could.
I take it that you're talking about the order in which things are presented in the documentation. I think that expanding the tutorial into something closer to the quick start will be beneficial for people without a FP background, and I'm taking a note to do it. That section will come after the quick start and before the "type classes" section, and will present the most concrete and important type classes used all the time (Comparable, Functor, Foldable, Iterable). People who want to read about Applicatives, Monads and Traversables will have the reference for that.
It would be nice to see the docs divide into something like:
- The basic type concepts(such as `type<>`, integral constants, metafunctionn, etc)
- The basic sequence concepts, what concepts are necessary to define a hana sequence, and the different sequences
- Accessing data from a hana sequence, such as `at`, `front`, `back`
- Views or adaptors on sequences, such as filter, transform
- Algorithms on sequences, such as `fold`, `max`, etc
- Extending Boost.Hana
Ok, my previous paragraph is basically that. I agree with you, and I think this is a better way of presenting things.
Those are some thoughts after reading through the library. Perhaps, I missed some design goals you have.
Thanks so much for your comments. Louis