Efficient tuple implementation
Hi,
I recently discovered (or maybe not) a neat trick to implement a tuple-like
container. The technique has a couple of drawbacks which I will explain later.
For a real example, you can see my list implementation in Boost.Hana at [1].
Here's the idea:
auto list = [](auto ...xs) {
return [=](auto access) { return access(xs...); };
};
auto head = [](auto xs) {
return xs([](auto first, auto ...rest) { return first; });
};
auto tail = [](auto xs) {
return xs([](auto first, auto ...rest) { return list(rest...); });
};
auto length = [](auto xs) {
return xs([](auto ...z) { return sizeof...(z); });
};
// etc...
// then use it like
auto three = length(list(1, '2', "3"));
The idea is to use the capture of the lambda as a fast compiler-generated
struct with the desired members. By passing a function to that lambda, we
get an access to the unpacked representation of those members and we can
then apply any fast algorithm on parameter packs.
Drawbacks
---------
1. The type of that tuple is completely opaque. Hence, it is harder to debug,
but I'm working on other stuff that should make this a moot point.
2. Since lambdas can't be made constexpr, this tuple can't either. However,
there was some discussion about proposing constexpr lambdas at C++Now
and it looked like there was a lot of support for the idea, so this
might change.
Benchmarks
----------
I ran a couple of benchmarks testing the compilation time and the results
are self explanatory. The benchmark suite is at [2].
## Create a tuple of n elements
The test code looks like:
#include
On Sat, Jun 07, 2014 at 02:22:27AM +0000, Louis Dionne wrote:
Louis Dionne
writes: [...]
<a href="http://imgur.com/rKqmvk3"><img src="http://i.imgur.com/rKqmvk3.png"/></a>
Ew, sorry about that. How can I post images on this list?
Mailing lists are (should be) pure plain text delivered as mail. You can attempt to post HTML mail and feel the anger of a thousand subscribers and being ignored by anyone who cannot or refuse to attempt to read HTML soup. A naked URL will typically be recognized and linkified by clever enough mail readers, and if they're not, anyone interested can copy/paste it if they feel it's interesting enough. -- Lars Viklund | zao@acc.umu.se
On 06/06/2014 11:18 p.m., Louis Dionne wrote:
Hi,
I recently discovered (or maybe not) a neat trick to implement a tuple-like container. The technique has a couple of drawbacks which I will explain later. For a real example, you can see my list implementation in Boost.Hana at [1]. Here's the idea:
auto list = [](auto ...xs) { return [=](auto access) { return access(xs...); }; };
auto head = [](auto xs) { return xs([](auto first, auto ...rest) { return first; }); };
auto tail = [](auto xs) { return xs([](auto first, auto ...rest) { return list(rest...); }); };
auto length = [](auto xs) { return xs([](auto ...z) { return sizeof...(z); }); };
// etc... // then use it like
auto three = length(list(1, '2', "3"));
The idea is to use the capture of the lambda as a fast compiler-generated struct with the desired members. By passing a function to that lambda, we get an access to the unpacked representation of those members and we can then apply any fast algorithm on parameter packs.
We have experimented with lambdas in Spirit.X3 as a way to drastically reduce compile times (although not in the form of tuples), and I would like to add some information on the why. The unique feature of lambdas is that name mangling is independent of the captures (at least in Itanium and Microsoft ABIs), so their symbol length remains the same (for all intent and purposes) regardless of the number of member captures and the length of their types. This is not true of templates, and it is what dominates the compilation time and memory usage nowadays. Lambdas have opaque mangled names, effectively acting as a mangler firewall. Regards, -- Agustín K-ballo Bergé.- http://talesofcpp.fusionfenix.com
On 06/06/14 21:56, Agustín K-ballo Bergé wrote:
On 06/06/2014 11:18 p.m., Louis Dionne wrote:
Hi,
I recently discovered (or maybe not) a neat trick to implement a tuple-like container. The technique has a couple of drawbacks which I will explain later. For a real example, you can see my list implementation in Boost.Hana at [1]. [snip] The idea is to use the capture of the lambda as a fast compiler-generated struct with the desired members. By passing a function to that lambda, we get an access to the unpacked representation of those members and we can then apply any fast algorithm on parameter packs.
We have experimented with lambdas in Spirit.X3 as a way to drastically reduce compile times (although not in the form of tuples),
Are you referring to the make_opaque mentioned here: http://article.gmane.org/gmane.comp.parsers.spirit.general/26634 or something else? If something else, could we have a peek at it somewhere? -regards, Larry
On 12/06/2014 02:59 p.m., Larry Evans wrote:
On 06/06/14 21:56, Agustín K-ballo Bergé wrote:
On 06/06/2014 11:18 p.m., Louis Dionne wrote:
Hi,
I recently discovered (or maybe not) a neat trick to implement a tuple-like container. The technique has a couple of drawbacks which I will explain later. For a real example, you can see my list implementation in Boost.Hana at [1]. [snip] The idea is to use the capture of the lambda as a fast compiler-generated struct with the desired members. By passing a function to that lambda, we get an access to the unpacked representation of those members and we can then apply any fast algorithm on parameter packs.
We have experimented with lambdas in Spirit.X3 as a way to drastically reduce compile times (although not in the form of tuples),
Are you referring to the make_opaque mentioned here:
http://article.gmane.org/gmane.comp.parsers.spirit.general/26634
or something else? If something else, could we have a peek at it somewhere?
Yes, I was referring to `make_opaque` (and the debate that followed on IRC). The goal was to hide the excessively long symbol names generated by a fusion map of expression templates. Then Joel came up with the idea of representing those maps via ADL instead. Regards, -- Agustín K-ballo Bergé.- http://talesofcpp.fusionfenix.com
On 7 Jun 2014 at 2:18, Louis Dionne wrote:
Also, for those following the development of Boost.Hana, it is going well and I am preparing for a followup in the near future. Stay tuned!
Louis, Microsoft have announced what's going to be in VS2015 at http://blogs.msdn.com/b/vcblog/archive/2014/06/03/visual-studio-14-ctp .aspx. I was wondering if Boost.Hana could work with VS2015? I mean, VS2014 will clearly be insufficient, but I'd like to know what you think about VS2015. Note that VS2015 still will not have expression SFINAE nor generalised constexpr nor template variables. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
Niall Douglas
On 7 Jun 2014 at 2:18, Louis Dionne wrote:
Also, for those following the development of Boost.Hana, it is going well and I am preparing for a followup in the near future. Stay tuned!
Louis, Microsoft have announced what's going to be in VS2015 at http://blogs.msdn.com/b/vcblog/archive/2014/06/03/visual-studio-14-ctp .aspx.
I can't access this without signing up, but see below.
I was wondering if Boost.Hana could work with VS2015? I mean, VS2014 will clearly be insufficient, but I'd like to know what you think about VS2015. Note that VS2015 still will not have expression SFINAE nor generalised constexpr nor template variables.
Variable templates and generalized constexpr are used in the library. Workarounds _might_ be possible, but I have to say I'm unwilling to make the code less legible in favour of workarounds since Boost.Hana is a bleeding edge library. Still, if something can easily be done about it and make the library usable by massively more people, I will. Regards, Louis
On 7 Jun 2014 at 15:09, Louis Dionne wrote:
Also, for those following the development of Boost.Hana, it is going well and I am preparing for a followup in the near future. Stay tuned!
Louis, Microsoft have announced what's going to be in VS2015 at http://blogs.msdn.com/b/vcblog/archive/2014/06/03/visual-studio-14-ctp .aspx.
I can't access this without signing up, but see below.
Eh, no it's definitely public. Check the link is correct, no spaces etc. Failing that search google for Visual Studio "14" CTP.
I was wondering if Boost.Hana could work with VS2015? I mean, VS2014 will clearly be insufficient, but I'd like to know what you think about VS2015. Note that VS2015 still will not have expression SFINAE nor generalised constexpr nor template variables.
Variable templates and generalized constexpr are used in the library. Workarounds _might_ be possible, but I have to say I'm unwilling to make the code less legible in favour of workarounds since Boost.Hana is a bleeding edge library.
Still, if something can easily be done about it and make the library usable by massively more people, I will.
Well, you know the way you've been experimenting with alternative ways of doing the same thing ... I was thinking you could have a good Hana and a bad Hana :). Good Hana is close to optimal for clang and GCC, while bad Hana is more backwards compatible at the cost of pathological performance. You'd obviously have preprocessor which switches the underlying implementation depending on the compiler. Do also bear in mind that MSVC is not an AST based compiler, so all your benchmarks will look totally different on MSVC anyway. What may have O(N^N) scaling on an AST compiler might well be O(N) on MSVC - in fact, that is exactly why MSVC isn't AST based, as internal Microsoft code is so complex it is uncompilable by an AST based compiler. So if you are to support MSVC one day after C++ 14 conformance is reached, the techniques you currently optimise for may well not be useful. And MSVC isn't going anywhere. It's going to be a Tier 1 C++ compiler for at least the next decade. This might help your design choices today. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
Niall Douglas
On 7 Jun 2014 at 15:09, Louis Dionne wrote:
Also, for those following the development of Boost.Hana, it is going well and I am preparing for a followup in the near future. Stay tuned!
Louis, Microsoft have announced what's going to be in VS2015 at http://blogs.msdn.com/b/vcblog/archive/2014/06/03/visual-studio-14-ctp .aspx.
I can't access this without signing up, but see below.
Eh, no it's definitely public. Check the link is correct, no spaces etc. Failing that search google for Visual Studio "14" CTP.
My bad, the link was fine.
I was wondering if Boost.Hana could work with VS2015? I mean, VS2014 will clearly be insufficient, but I'd like to know what you think about VS2015. Note that VS2015 still will not have expression SFINAE nor generalised constexpr nor template variables.
Variable templates and generalized constexpr are used in the library. Workarounds _might_ be possible, but I have to say I'm unwilling to make the code less legible in favour of workarounds since Boost.Hana is a bleeding edge library.
Still, if something can easily be done about it and make the library usable by massively more people, I will.
Well, you know the way you've been experimenting with alternative ways of doing the same thing ...
I was thinking you could have a good Hana and a bad Hana :). Good Hana is close to optimal for clang and GCC, while bad Hana is more backwards compatible at the cost of pathological performance. You'd obviously have preprocessor which switches the underlying implementation depending on the compiler.
That's an idea; I'm noting it and I'll think about it when the time is ripe. Right now, I'm experimenting a lot and it would be dumb to make my job harder by supporting workarounds, but that won't be true forever.
Do also bear in mind that MSVC is not an AST based compiler, so all your benchmarks will look totally different on MSVC anyway. What may have O(N^N) scaling on an AST compiler might well be O(N) on MSVC - in fact, that is exactly why MSVC isn't AST based, as internal Microsoft code is so complex it is uncompilable by an AST based compiler. So if you are to support MSVC one day after C++ 14 conformance is reached, the techniques you currently optimise for may well not be useful.
And MSVC isn't going anywhere. It's going to be a Tier 1 C++ compiler for at least the next decade. This might help your design choices today.
Actually, I'm trying to keep the API very independent from the internal implementation. The way I see it so far, performing well on MSVC will be a matter of benchmarking on that compiler and selecting the right implementation internally, and we won't wish that we had a different API. Still, benchmarking on MSVC is something that I have not done yet because I don't have access to that compiler. This is on my todo list, right after making Boost.Hana compilable by GCC. :-) Regards, Louis
[Niall Douglas]
Do also bear in mind that MSVC is not an AST based compiler, so all your benchmarks will look totally different on MSVC anyway. What may have O(N^N) scaling on an AST compiler might well be O(N) on MSVC - in fact, that is exactly why MSVC isn't AST based, as internal Microsoft code is so complex it is uncompilable by an AST based compiler.
1. That's not why. The reason is that manipulating tokens seemed like a good idea 20-30 years ago, when this was sufficient to deal with C and C++ (before templates, variadic templates, decltype, constexpr, expression SFINAE, etc.) when computers were far smaller and slower. 2. MS has a whole bunch of code, but only a tiny fraction approaches the complexity of Boost (in terms of "doing tricky things with the language"; stuff that's just loops and pointers is not complicated by this metric, no matter how twisty). Our STL implementation is usually the high water mark for complexity, and while we do tricky stuff, I know that Boost is trickier. 3. I am not really qualified to talk about compiler tech, but I cannot possibly understand how keeping an AST around would change the *asymptotic* complexity of translation (it introduces constant factors which are an issue in practice). The AST has a strict superset of the information available by looking at a few tokens at a time. By definition, any speedups with a token-based approach that can't be obtained through an AST would be due to nonconformance. STL
On 8 Jun 2014 at 18:37, Stephan T. Lavavej wrote:
Do also bear in mind that MSVC is not an AST based compiler, so all your benchmarks will look totally different on MSVC anyway. What may have O(N^N) scaling on an AST compiler might well be O(N) on MSVC - in fact, that is exactly why MSVC isn't AST based, as internal Microsoft code is so complex it is uncompilable by an AST based compiler.
1. That's not why. The reason is that manipulating tokens seemed like a good idea 20-30 years ago, when this was sufficient to deal with C and C++ (before templates, variadic templates, decltype, constexpr, expression SFINAE, etc.) when computers were far smaller and slower.
For a good chunk of MSVC's (and C++'s) userbase, template use never really exceeds cookie cutter use i.e. template<class T> class vector. And for those guys - which includes a good chunk of Microsoft itself - MSVC's approach makes perfect sense. It is after all blindingly quick, and uses virtually no RAM relatively speaking. By "internal Microsoft code is so complex it is uncompilable by an AST based compiler" I was referring to a conversation I had with Gaby and James McNellis at C++ Now with Chandler occasionally jumping in to confirm the insanity :). They were telling me about the problems of getting 18k line long functions to compile with *any* AST based compiler, and that a unique problem facing MSVC is that a ton of Microsoft internal code is automatically generated in a way done under the expectation that MSVC doesn't mind really long statements such as an if() statement spanning a few thousand lines. One then faces the choice of retrofixing those automated generators to produce less insane output, or keep MSVC non-AST based for non-template non-constexpr code. I was told to date the latter has been chosen.
2. MS has a whole bunch of code, but only a tiny fraction approaches the complexity of Boost (in terms of "doing tricky things with the language"; stuff that's just loops and pointers is not complicated by this metric, no matter how twisty). Our STL implementation is usually the high water mark for complexity, and while we do tricky stuff, I know that Boost is trickier.
Oh sure. I didn't clarify I meant things like a single boolean if containing thousands of tests. I meant sheer size complexity, not language complexity.
3. I am not really qualified to talk about compiler tech, but I cannot possibly understand how keeping an AST around would change the *asymptotic* complexity of translation (it introduces constant factors which are an issue in practice). The AST has a strict superset of the information available by looking at a few tokens at a time. By definition, any speedups with a token-based approach that can't be obtained through an AST would be due to nonconformance.
The problem is RAM consumption, because you need to create an AST for the item being compiled before you compile it. Louis' empirical tests for MPL11 (now Hana) implementation solutions did a lot of time and space comparisons for various metaprogramming techniques. Both clang and GCC are AST based, so their space consumption graphs looked not dissimilar. MSVC has taken considerable effort to use sane amounts of RAM under very trying conditions, so I would suspect without evidence that MSVC would produce *very* different graphs - some worse, but probably many better. What is O(N^2) on clang or GCC I could see being O(N) on MSVC for example simply due to lack of two phase lookup. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
On Sat, Jun 7, 2014 at 6:44 AM, Niall Douglas
On 7 Jun 2014 at 2:18, Louis Dionne wrote:
Also, for those following the development of Boost.Hana, it is going well and I am preparing for a followup in the near future. Stay tuned!
Louis, Microsoft have announced what's going to be in VS2015 at http://blogs.msdn.com/b/vcblog/archive/2014/06/03/visual-studio-14-ctp .aspx.
I was wondering if Boost.Hana could work with VS2015? I mean, VS2014 will clearly be insufficient, but I'd like to know what you think about VS2015. Note that VS2015 still will not have expression SFINAE nor generalised constexpr nor template variables.
A couple of nits: We don't actually know the name of the next VS release, although we know `Visual Studio "14" will most likely be available sometime in 2015, with a more complete preview release and final naming available later this year.` Also, the roadmap published at the bottom of http://blogs.msdn.com/b/somasegar/archive/2014/05/28/first-preview-of-visual... is just their current best guess. For example, "inline namespaces" was off in the distant future, but when the LWG started using inline namespaces in the TSes, Microsoft implemented them right away. --Beman
On 7 Jun 2014 at 11:14, Beman Dawes wrote:
We don't actually know the name of the next VS release, although we know `Visual Studio "14" will most likely be available sometime in 2015, with a more complete preview release and final naming available later this year.`
Also, the roadmap published at the bottom of http://blogs.msdn.com/b/somasegar/archive/2014/05/28/first-preview-of-visual... is just their current best guess. For example, "inline namespaces" was off in the distant future, but when the LWG started using inline namespaces in the TSes, Microsoft implemented them right away.
I think it safe to say that if a feature is in a CTP, it is extremely likely to appear in a production compiler sooner rather than later. One can therefore state, with some certainty, what featureset a VS2015 will as a minimum likely have. I certainly can see that generalised constexpr will be hard for Microsoft. They'd need an internal constexpr-only C++ compiler as theirs is not an AST based compiler. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
Louis Dionne wrote:
Here's the idea:
auto list = [](auto ...xs) { return [=](auto access) { return access(xs...); }; };
auto head = [](auto xs) { return xs([](auto first, auto ...rest) { return first; }); };
That's very clever. It's also a good example of how C++ continues to acquire expressive power and surprise us after 16 years of being an ISO standard.
On 06/07/2014 06:37 AM, Peter Dimov wrote:
Louis Dionne wrote:
Here's the idea:
auto list = [](auto ...xs) { return [=](auto access) { return access(xs...); }; };
auto head = [](auto xs) { return xs([](auto first, auto ...rest) { return first; }); };
That's very clever.
It's also a good example of how C++ continues to acquire expressive power and surprise us after 16 years of being an ISO standard.
Agreed. I love it. And since C++14 lambdas support move capture, this can do perfect forwarding, too. \e
On 06/06/14 21:18, Louis Dionne wrote:
Hi,
I recently discovered (or maybe not) a neat trick to implement a tuple-like container. The technique has a couple of drawbacks which I will explain later. For a real example, you can see my list implementation in Boost.Hana at [1]. Here's the idea:
auto list = [](auto ...xs) { return [=](auto access) { return access(xs...); }; };
auto head = [](auto xs) { return xs([](auto first, auto ...rest) { return first; }); };
auto tail = [](auto xs) { return xs([](auto first, auto ...rest) { return list(rest...); }); };
auto length = [](auto xs) { return xs([](auto ...z) { return sizeof...(z); }); };
// etc... // then use it like
auto three = length(list(1, '2', "3"));
IIRC, list uses an evaluator and "tagged" lists where the 1st element in the list is a tag for the operation to be performed and the evaluator dispatches on this tag to do the operation with the operands being the remaining args in the list. The attached is my first attempt at doing something similar with the idea you propose. I'm wondering if spirit might use something similar where the tags, instead of being op_or or op_and, would be op_alt and op_seq where op_alt would correspond to the alternative parser: http://www.boost.org/doc/libs/1_55_0/libs/spirit/doc/html/spirit/qi/referenc... and op_seq would correspond to the sequence parser: http://www.boost.org/doc/libs/1_55_0/libs/spirit/doc/html/spirit/qi/referenc... Does this look useful? Any suggested improvements would be appreciated. -regards, Larry
Larry Evans
On 06/06/14 21:18, Louis Dionne wrote:
[...]
IIRC, list uses an evaluator and "tagged" lists where the 1st element in the list is a tag for the operation to be performed and the evaluator dispatches on this tag to do the operation with the operands being the remaining args in the list.
I don't understand which list you are talking about. Are you talking about MPL11 lists, Hana lists or something else? MPL11 lists and Hana lists use type class based dispatching, so that would be incorrect if you were talking about those.
The attached is my first attempt at doing something similar with the idea you propose.
I'm wondering if spirit might use something similar where the tags, instead of being op_or or op_and, would be op_alt and op_seq where op_alt would correspond to the alternative parser:
http://www.boost.org/doc/libs/1_55_0/libs/spirit/doc/html/spirit/qi/referenc.... html
and op_seq would correspond to the sequence parser:
http://www.boost.org/doc/libs/1_55_0/libs/spirit/doc/html/spirit/qi/referenc... tml
Does this look useful? Any suggested improvements would be appreciated.
IIUC, tagged tuples are a kind of dispatching system, right? If so, I don't see the gain over a traditional tag (or type class) based dispatching. I might be missing something; could you please explain? Regards, Louis
On 06/15/14 08:44, Louis Dionne wrote:
Larry Evans
writes: On 06/06/14 21:18, Louis Dionne wrote:
[...]
IIRC, list uses an evaluator and "tagged" lists where the 1st element in
^^^^ should be lisp
the list is a tag for the operation to be performed and the evaluator dispatches on this tag to do the operation with the operands being the remaining args in the list.
I don't understand which list you are talking about.
OOPS. Very sorry for the typo above. I'm talking about the language, Lisp: http://en.wikipedia.org/wiki/Lisp_%28programming_language%29 and the pattern I was talking about was called "Polish prefix notation" in the wikipedia article. -regards, Larry
Larry Evans
On 06/15/14 08:44, Louis Dionne wrote:
Larry Evans
writes: On 06/06/14 21:18, Louis Dionne wrote:
[...]
IIRC, list uses an evaluator and "tagged" lists where the 1st element in
^^^^ should be lisp
the list is a tag for the operation to be performed and the evaluator dispatches on this tag to do the operation with the operands being the remaining args in the list.
I don't understand which list you are talking about.
OOPS. Very sorry for the typo above. I'm talking about the language, Lisp:
http://en.wikipedia.org/wiki/Lisp_%28programming_language%29
and the pattern I was talking about was called "Polish prefix notation" in the wikipedia article.
Ok, now I understand better. As for your question, I did not follow the development of Spirit X3 close enough to know for sure. However, if you have to store variadic arguments, using a lambda somewhere in there is probably the most efficient way. And as soon as you have stuff in a variadic representation, it's better if you keep it that way because most algorithms will perform better on variadic packs. The way I see it for Boost.Hana, your dispatching system could be used internally as an optimization to dispatch efficient operations on variadics, while keeping the more flexible type class based dispatching interface. I'll keep that on the back of my head for when I start optimizing seriously. Thanks, Louis
On 06/16/14 18:55, Louis Dionne wrote:
Larry Evans
writes: On 06/15/14 08:44, Louis Dionne wrote:
Larry Evans
writes: On 06/06/14 21:18, Louis Dionne wrote:
[...]
IIRC, list uses an evaluator and "tagged" lists where the 1st element in
^^^^ should be lisp
the list is a tag for the operation to be performed and the evaluator dispatches on this tag to do the operation with the operands being the remaining args in the list.
I don't understand which list you are talking about.
OOPS. Very sorry for the typo above. I'm talking about the language, Lisp:
http://en.wikipedia.org/wiki/Lisp_%28programming_language%29
and the pattern I was talking about was called "Polish prefix notation" in the wikipedia article.
Ok, now I understand better. As for your question, I did not follow the development of Spirit X3 close enough to know for sure. However, if you have to store variadic arguments, using a lambda somewhere in there is probably the most efficient way. And as soon as you have stuff in a variadic representation, it's better if you keep it that way because most algorithms will perform better on variadic packs.
The way I see it for Boost.Hana, your dispatching system could be used internally as an optimization to dispatch efficient operations on variadics, while keeping the more flexible type class based dispatching interface. I'll keep that on the back of my head for when I start optimizing seriously.
Thanks, Louis
A more complete example, which uses operators || and && to create the tagged tuples, is now here: https://gist.github.com/cppljevans/01e23df914916ea7d16e The use of the operators make it more like what spirit does with, for example, operators | and >>. However, I still don't have a good idea of how useful this will be. Only more experimentation can tell. Hopefully others may have some ideas on how to use this. -regards, Larry
On 06/17/14 10:02, Larry Evans wrote: [snip]
A more complete example, which uses operators || and && to create the tagged tuples, is now here:
Correction of above for the op_and is here: https://gist.github.com/cppljevans/01e23df914916ea7d16e/68db5988826ad4fc4dad... Is there some way to encapsulate op_and, or_or, false_ and true_ in some sort of typeclass for a boolean lattice: http://en.wikipedia.org/wiki/Boolean_algebra_%28structure%29 ? It seems if I had used such a typeclass, it would be more likely that I would have avoided the above copy&paste error by forcing me to be more careful. -regards, Larry
Larry Evans
[...]
Is there some way to encapsulate op_and, or_or, false_ and true_ in some sort of typeclass for a boolean lattice:
http://en.wikipedia.org/wiki/Boolean_algebra_%28structure%29
?
It seems if I had used such a typeclass, it would be more likely that I would have avoided the above copy&paste error by forcing me to be more careful.
It ought to be possible, at least in principle. I'm not sure how much it would be useful (at least for Boost.Hana), but I'll think about it. The real problem I see is how to implement short-circuiting for the boolean operations. Since C++ has strict semantics, we have to resort to a library- based approach, and that raises some issues. If you are interested, you can take a look at my Logical type class implementation in Boost.Hana [1]. While it does not describe a boolean algebra, it handles conjunction, disjunction and branching. I am unsatisfied with it though, and I'm currently trying to improve it. Regards, Louis [1]: https://github.com/ldionne/hana/blob/master/include/boost/hana/logical.hpp
participants (9)
-
Agustín K-ballo Bergé
-
Beman Dawes
-
Eric Niebler
-
Larry Evans
-
Lars Viklund
-
Louis Dionne
-
Niall Douglas
-
Peter Dimov
-
Stephan T. Lavavej