However, even though you may be content with the ease of writing TMP code in C++14, I think you might be surprised to see how shorter it could be if you used Hana. This is, for example, the case of Zach's Units-BLAS library. It was really quite short with C++14 only, but it was even shorter with Hana. And the code was written with a higher level of abstraction. And in that case, there was even a compile-time speedup over std::tuple + handwritten stuff.
"really quite short" is good enough if the cost is having to depend on a "32k header mega library" as David notes. Not to mention having to learn another library for me and for all future maintainers.
Louis Dionne respondeth:
Regarding the "32k header mega library" thing, I'd like to precise that it's not as bad as it seems. First, part of it is just documentation. Second, that's a _real_ 32 kLOC, not a 100 kLOC of dependencies hidden behind a 5 kLOC library. Hana as no dependencies except the
, <utility> and <cstddef> headers, which you probably already use anyway. In comparison, including almost any other Boost library will pull in a lot more than 32 kLOCs in dependencies.
This.
For TMP libraries, and particularly for their application in large
production codebases, I conclude the following pattern tends to hold: MORE
IS LESS.
Paraphrased, this would be, "More reusable code in libraries means less
application-specific code is necessary, so the program is more feature-rich
and functionality evolves better over time."
Explanation: A "richer" (well-defined/implemented) library tends to
provide non-linear value improvements over a "smaller" library.
In large codebases, a "more-complete" library is superior because:
(a) (Real-world) Corner cases are addressed. When confronted with a given
corner case that is unaddressed by the limited ambitions of the smaller
library, you write adapter layers which can be brittle or expensive in many
ways, and which possibly don't really do what you wanted. These tend to be
inconsistently adapted/used across the codebase, which is bad, because it
should have been centralized somehow (such as through a reusable library).
(b) It becomes unnecessary to also rely upon other (overlapping) libraries
that usually offer a different metaphor, but which sufficiently overlap
with functionality as to cause confusion among developers (because there is
now, "more than one way" to do some things).
(c) Efficiencies are possible within the library implementation. Those
additional corner cases can be addressed and short-circuited, but as we all
know, for TMP this often relies upon more (partial-)specializations
(requiring more code).
I like Hana's approach because it is unifying, and presents a single
consistent model. Like Zach said, I don't see it as "big" -- I only care
about that small interface that is relevant for my needs, and my
production-code is smaller/less.
That 32K includes extensive comments (which can be stripped if necessary),
but I think it's particularly awesome that it is truly uncoupled from
almost everything (needing only
To do much better, we would probably need a compiler-provided closure type. Basically, std::tuple as a compiler intrinsic. I think this could be lightning fast, but we're not there yet.
Hey, that's a really great idea. I could come up with lots of uses for that. --charley