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.
I understand how it is simpler to define sequences using `head`/`tail`, but how is it more expressive?
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 believe Alex Stepanov would like to have a word with you ;)
I did try using both.
What limitiation did you run into seperating "Sequences" and "Algorithms"?
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.
Yet it uses a lot of foreign functional concepts. Despite what google says, boost libraries are built around mostly C++-like 'interfaces'. I don't think its bad to introduce some functional-interfaces, but I know in the past libraies that libraries that were very functional were rejected from boost, because many people didn't grasp the purpose of them. So introducing a lot of functional interfaces on the surface of a library can hinder its adoption. Also, the uses concepts that have a default methods are not very common. In general, a C++ concept defines a core set of functionality that can be used to extend a library.
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?
Yes, change the structure of the typeclasses. For example, `Iterable` has
`for_each` included(which is defaulted). However, you could seperate
`for_each` out as an algorithm that requires an `Iterable`. Then have a
seperate mechanism to override the algorithms, such as for varidiac
templates:
template class Sequence, class... Ts>
struct algorithm
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.
Even so, in your implementation of list.hpp, it may not be performance hit to include it together, but perhaps as a user, I could be adapting a type where each of those methods are heavyweight, so I would want to seperate them out into seperate headers.
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.
Just as non-member functions are preferred when they only access public members, I believe this same advice can be applied here. Each method that has a default implementation could be made as a seperate function(which could be designed to be overloaded as well). -- View this message in context: http://boost.2283326.n4.nabble.com/Re-GSoC-Boost-Hana-Formal-review-request-... Sent from the Boost - Dev mailing list archive at Nabble.com.