Interest in updated expression template library?
I'm trying to gauge interest in submitting a library to the review queue, It's an expression template library called Yap using C++14 and C++17 features, built on top of Hana. It does not work quite the same as Proto, though of course it covers the same problem domain. My goal for the library was to cover the Proto functionality (while allowing the user to write less code than she would have had to with Proto) plus more functionality made easier by the new language features. In the examples you will find nearly all of the Proto examples reproduced, each in a-bit-less to dramatically-less code. The only Proto examples that were left out were ones that are now trivial using Yap due to differences in design. Online docs: https://tzlaine.github.io/yap GiHub page: https://github.com/tzlaine/yap Zach
On 1/10/2017 9:35 AM, Zach Laine wrote:
I'm trying to gauge interest in submitting a library to the review queue, It's an expression template library called Yap using C++14 and C++17 features, built on top of Hana.
It does not work quite the same as Proto, though of course it covers the same problem domain. My goal for the library was to cover the Proto functionality (while allowing the user to write less code than she would have had to with Proto) plus more functionality made easier by the new language features.
In the examples you will find nearly all of the Proto examples reproduced, each in a-bit-less to dramatically-less code. The only Proto examples that were left out were ones that are now trivial using Yap due to differences in design.
Online docs:
GiHub page:
There should be a list of all the Boost libraries on which Yap immediately depends. Is it just Hana, or are there others ?
On Tue, Jan 10, 2017 at 12:32 PM, Edward Diener
There should be a list of all the Boost libraries on which Yap immediately depends. Is it just Hana, or are there others ?
It also depends on TypeIndex for type printing, but only if you include the optional print.hpp header, and it depends on a single header from PP. Zach
On 10/01/2017 20:37, Zach Laine wrote:
On Tue, Jan 10, 2017 at 12:32 PM, Edward Diener
wrote: There should be a list of all the Boost libraries on which Yap immediately depends. Is it just Hana, or are there others ?
It also depends on TypeIndex for type printing, but only if you include the optional print.hpp header, and it depends on a single header from PP.
Zach
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost Nice that this is optional, to get Boost.Spirit based code small enough to fit in Cortex M0 mcus with 64kb ROM, we currently have to patch our Boost headers to remove the debug printing headers with the current Proto.
I think if there is an emphasis on object size reduction and compile time reduction there will be definitely an interest to switch from Proto to Yap. Did you already make some benchmarking comparing Proto to Yap in this regard ?
On Tue, Jan 10, 2017 at 2:00 PM, Damien Buhl
Nice that this is optional, to get Boost.Spirit based code small enough to fit in Cortex M0 mcus with 64kb ROM, we currently have to patch our Boost headers to remove the debug printing headers with the current Proto.
I think if there is an emphasis on object size reduction and compile time reduction there will be definitely an interest to switch from Proto to Yap. Did you already make some benchmarking comparing Proto to Yap in this regard ?
I have not compared Yap to Proto. I have however compared Yap to hand-written code. It compares favorably. There's a "make perf" build target for Yap that spits out assembly (among other things) if you want to look for yourself. Zach
On 10 January 2017 at 14:35, Zach Laine
I'm trying to gauge interest in submitting a library to the review queue, It's an expression template library called Yap using C++14 and C++17 features, built on top of Hana.
It does not work quite the same as Proto, though of course it covers the same problem domain. My goal for the library was to cover the Proto functionality (while allowing the user to write less code than she would have had to with Proto) plus more functionality made easier by the new language features.
I've personally played a lot with expression templates, with and without Proto. Very quickly it becomes hairy, consumes huge amounts of memory that is never reclaimed, and takes very long to compile. I don't know how much better it is with Yap, but that's definitely a major problem and any new solution should try to address it. Symbols need to be short, and no evaluation should ever depend on the scalability of overloading or partial template specializations. The design used by Eigen or by some valarray implementations, while not necessarily the most elegant, is simple and scales well, but involves coupling the representation of the tree with its evaluation.
On Tue, Jan 10, 2017 at 1:45 PM, Mathias Gaunard < mathias.gaunard@ens-lyon.org> wrote:
On 10 January 2017 at 14:35, Zach Laine
wrote: I've personally played a lot with expression templates, with and without Proto. Very quickly it becomes hairy, consumes huge amounts of memory that is never reclaimed, and takes very long to compile. I don't know how much better it is with Yap, but that's definitely a major problem and any new solution should try to address it. Symbols need to be short, and no evaluation should ever depend on the scalability of overloading or partial template specializations.
I agree with all of these complaints. This is in fact why I wrote Yap. The compile times are very good, even for an obnoxious number of terminals (thousands), and there is no memory allocated at all -- or did you mean compiler memory usage? I haven't looked at that.
The design used by Eigen or by some valarray implementations, while not necessarily the most elegant, is simple and scales well, but involves coupling the representation of the tree with its evaluation.
My hope is that the Yap design is easy enough to use that custom ET code is no longer necessary. Zach
On 10 January 2017 at 20:07, Zach Laine
I agree with all of these complaints. This is in fact why I wrote Yap. The compile times are very good, even for an obnoxious number of terminals (thousands), and there is no memory allocated at all -- or did you mean compiler memory usage? I haven't looked at that.
Compiler memory usage of course. When a TU takes 4GB to compile or more, it leads to lots of problems, even if RAM is cheap and you could put hundreds of gigabytes in your build server.
On 01/10/2017 04:22 PM, Mathias Gaunard wrote:
On 10 January 2017 at 20:07, Zach Laine
wrote: I agree with all of these complaints. This is in fact why I wrote Yap. The compile times are very good, even for an obnoxious number of terminals (thousands), and there is no memory allocated at all -- or did you mean compiler memory usage? I haven't looked at that.
Compiler memory usage of course. When a TU takes 4GB to compile or more, it leads to lots of problems, even if RAM is cheap and you could put hundreds of gigabytes in your build server.
Zach, w.r.t. compile-time benchmarking, Louis has a compiler benchmark library here: https://github.com/ldionne/metabench I did have a brief look at it; however, I didn't see an easy way to vary parameters of the benchmark, for example, the size of expressions, and compare the results (it uses embedded ruby, and I couldn't figure out from that how to do what I want). Instead, I resorted to gmake for loops, as shown here: https://github.com/cppljevans/spirit/blob/get_rhs/workbench/x3/rule_defns/Ma... resulting in output shown here: https://github.com/cppljevans/spirit/blob/get_rhs/workbench/x3/rule_defns/be... Interestingly enough, the method that performed worse was the one (RULE2RHS_CTX_LIST) which stored the rule2rhs information in the context. In contrast, the GET_RHS_CRTP stored this information by overloading functions generated by macros. What's interesting is that, based on what Brook Milligan says in his message, proto uses a context as well, but your library uses a set of function overloads. With regard to the gmake method of comparing compiler times, I realize that's sorta kludgy, and, years ago, I used a series of python programs to do the equivalent. I you find the gmake-for-loop method unacceptable, I can try to find the python method instead. HTH. -regards, Larry
On Wed, Jan 11, 2017 at 2:00 AM, Larry Evans
On 01/10/2017 04:22 PM, Mathias Gaunard wrote:
On 10 January 2017 at 20:07, Zach Laine
wrote: I agree with all of these complaints. This is in fact why I wrote Yap. The compile times are very good, even for an obnoxious number of terminals (thousands), and there is no memory allocated at all -- or did you mean compiler memory usage? I haven't looked at that.
Compiler memory usage of course. When a TU takes 4GB to compile or more, it leads to lots of problems, even if RAM is cheap and you could put hundreds of gigabytes in your build server.
Zach, w.r.t. compile-time benchmarking, Louis has a compiler benchmark library here:
Yes. It's quite nice.
I did have a brief look at it; however, I didn't see an easy way to vary parameters of the benchmark, for example, the size of expressions, and compare the results (it uses embedded ruby, and I couldn't figure out from that how to do what I want).
Instead, I resorted to gmake for loops, as shown here:
https://github.com/cppljevans/spirit/blob/get_rhs/workbench/ x3/rule_defns/Makefile#L97
resulting in output shown here:
https://github.com/cppljevans/spirit/blob/get_rhs/workbench/ x3/rule_defns/bench.tmp
Interestingly enough, the method that performed worse was the one (RULE2RHS_CTX_LIST) which stored the rule2rhs information in the context. In contrast, the GET_RHS_CRTP stored this information by overloading functions generated by macros. What's interesting is that, based on what Brook Milligan says in his message, proto uses a context as well, but your library uses a set of function overloads.
With regard to the gmake method of comparing compiler times, I realize that's sorta kludgy, and, years ago, I used a series of python programs to do the equivalent. I you find the gmake-for-loop method unacceptable, I can try to find the python method instead.
I haven't done much compile time benchmarking for Yap. It's fast enough that I haven't felt the need. If people start using Yap and noticing long compile times, I'll certainly do my best to fix that. Zach
On Tue, Jan 10, 2017 at 4:22 PM, Mathias Gaunard < mathias.gaunard@ens-lyon.org> wrote:
On 10 January 2017 at 20:07, Zach Laine
wrote: I agree with all of these complaints. This is in fact why I wrote Yap. The compile times are very good, even for an obnoxious number of
terminals
(thousands), and there is no memory allocated at all -- or did you mean compiler memory usage? I haven't looked at that.
Compiler memory usage of course. When a TU takes 4GB to compile or more, it leads to lots of problems, even if RAM is cheap and you could put hundreds of gigabytes in your build server.
Right. I would be very surprised to see that kind of thing when types are computed by saying "auto" instead of some tortuous metafunction. Zach
On Jan 10, 2017, at 7:35 AM, Zach Laine
wrote: In the examples you will find nearly all of the Proto examples reproduced, each in a-bit-less to dramatically-less code. The only Proto examples that were left out were ones that are now trivial using Yap due to differences in design.
As I am sure you know, Proto makes use of a context class to define the meaning of the expression trees. As a consequence, the same expression tree can be given different meanings by evaluating it with different context types. It seems that Yap defines the meaning in terms of a set of function overloads. Is it possible to give Yap expressions different meanings in the same sense that Proto does or is a single meaning encapsulated in the overload set? If the latter, then it seems that this should be pointed out explicitly in the documentation. If the former, clarifying how to accomplish this would be helpful. Cheers, Brook
On Tue, Jan 10, 2017 at 8:50 PM, Brook Milligan
On Jan 10, 2017, at 7:35 AM, Zach Laine
wrote: In the examples you will find nearly all of the Proto examples reproduced, each in a-bit-less to dramatically-less code. The only Proto examples that were left out were ones that are now trivial using Yap due to differences in design.
As I am sure you know, Proto makes use of a context class to define the meaning of the expression trees. As a consequence, the same expression tree can be given different meanings by evaluating it with different context types.
Right.
It seems that Yap defines the meaning in terms of a set of function overloads.
Yes and no. There are *implicit* transformations and evaluations that work based on extension points/function overloads; there can indeed only be one overload that gets selected, and this is implicitly chosen based on the normal overload resolution rules. There is also the explicit transform() function. This is what most of the examples use, and it is my preferred and recommended way of doing things. It allows you to define whatever transforms you like, including transforms that evaluate your expression in whole or in part. You can have as many of these as you like, and there is often no need to define a context per se. I say "per se" because the transform itself often looks much like a Proto context (e.g. it might be stateful). See the examples in the docs for details.
Is it possible to give Yap expressions different meanings in the same sense that Proto does or is a single meaning encapsulated in the overload set? If the latter, then it seems that this should be pointed out explicitly in the documentation. If the former, clarifying how to accomplish this would be helpful.
It is, as I said above. Something much like what I wrote above appears in the tutorial docs. Zach
On Jan 11, 2017, at 7:42 AM, Zach Laine
wrote: On Tue, Jan 10, 2017 at 8:50 PM, Brook Milligan
wrote: It seems that Yap defines the meaning in terms of a set of function overloads.
Yes and no. There are *implicit* transformations and evaluations that work based on extension points/function overloads; there can indeed only be one overload that gets selected, and this is implicitly chosen based on the normal overload resolution rules. There is also the explicit transform() function. This is what most of the examples use, and it is my preferred and recommended way of doing things. It allows you to define whatever transforms you like, including transforms that evaluate your expression in whole or in part. You can have as many of these as you like, and there is often no need to define a context per se. I say "per se" because the transform itself often looks much like a Proto context (e.g. it might be stateful). See the examples in the docs for details.
OK, I get it now. Your transforms are acting in much the same way that Proto contexts act. They define the interpretation of the expression tree when explicitly passed to the evaluate() function. Perhaps noting the connection (in a “comparison with / moving from Proto” section?) is worth noting, as I missed it at first. It seems that the reference documentation for evaluate() does not note that the transform argument is optional. Given your examples that call evaluate() with only a single argument, it seems to be optional. Is that also true for evaluate_as()? Should this be made explicit in the reference docs? Thanks for the clarification. Cheers, Brook
On Wed, Jan 11, 2017 at 12:03 PM, Brook Milligan
On Jan 11, 2017, at 7:42 AM, Zach Laine
wrote: On Tue, Jan 10, 2017 at 8:50 PM, Brook Milligan
wrote: It seems that Yap defines the meaning in terms of a set of function overloads.
Yes and no. There are *implicit* transformations and evaluations that work based on extension points/function overloads; there can indeed only be one overload that gets selected, and this is implicitly chosen based on the normal overload resolution rules. There is also the explicit transform() function. This is what most of the examples use, and it is my preferred and recommended way of doing things. It allows you to define whatever transforms you like, including transforms that evaluate your expression in whole or in part. You can have as many of these as you like, and there is often no need to define a context per se. I say "per se" because the transform itself often looks much like a Proto context (e.g. it might be stateful). See the examples in the docs for details.
OK, I get it now. Your transforms are acting in much the same way that Proto contexts act. They define the interpretation of the expression tree when explicitly passed to the evaluate() function. Perhaps noting the connection (in a “comparison with / moving from Proto” section?) is worth noting, as I missed it at first.
It seems that the reference documentation for evaluate() does not note that the transform argument is optional. Given your examples that call evaluate() with only a single argument, it seems to be optional. Is that also true for evaluate_as()? Should this be made explicit in the reference docs?
Thanks for the clarification.
evaluate() and evaluate_as() do not take a transform. They only evaluate. The optional params are used to supply values for placeholders. transform() takes a transform though. Though these points are covered if you read through the examples, it seems clear to me now that there needs to be a "Transforming and Evaluating Expressions" section in the tutorial. Zach
On Jan 11, 2017, at 12:11 PM, Zach Laine
wrote: evaluate() and evaluate_as() do not take a transform. They only evaluate. The optional params are used to supply values for placeholders. transform() takes a transform though.
Oops. My mistake. The links for “evaluate()” and “evaluate_as()” on the customization points doc page resolve to the documentation on the “transform()” function. I didn’t notice that discrepancy, assumed the page documented what the link implied, and saw the argument list. Sorry.
Though these points are covered if you read through the examples, it seems clear to me now that there needs to be a "Transforming and Evaluating Expressions" section in the tutorial.
That would be really helpful. I think much of the rest (which mainly includes making terminals and building expression trees using operators) is pretty clear, although I have not yet tried anything and may be missing something more (see below). The really critical part, I think, is understanding how to evaluate the expressions and what range of flexibility is possible. A section that outlines that explicitly would be great. I have not tried any of this yet because you are using constexpr-if statements, which are not supported by compilers I have access to just now. In fact, those are c++17 features, so I think the claim of c++14 compatibility is perhaps a bit bold. I look forward to trying this as soon as I can round up a compatible compiler. Cheers, Brook
On Wed, Jan 11, 2017 at 3:03 PM, Brook Milligan
On Jan 11, 2017, at 12:11 PM, Zach Laine
wrote: evaluate() and evaluate_as() do not take a transform. They only evaluate. The optional params are used to supply values for placeholders. transform() takes a transform though.
Oops. My mistake. The links for “evaluate()” and “evaluate_as()” on the customization points doc page resolve to the documentation on the “transform()” function. I didn’t notice that discrepancy, assumed the page documented what the link implied, and saw the argument list. Sorry.
Ha! Thanks, I'll fix that.
Though these points are covered if you read through the examples, it seems clear to me now that there needs to be a "Transforming and Evaluating Expressions" section in the tutorial.
That would be really helpful. I think much of the rest (which mainly includes making terminals and building expression trees using operators) is pretty clear, although I have not yet tried anything and may be missing something more (see below). The really critical part, I think, is understanding how to evaluate the expressions and what range of flexibility is possible. A section that outlines that explicitly would be great.
I have not tried any of this yet because you are using constexpr-if statements, which are not supported by compilers I have access to just now. In fact, those are c++17 features, so I think the claim of c++14 compatibility is perhaps a bit bold.
The use of constexpr if is guarded by a macro that is only defined if your compiler supports that feature. The CMake scripts build some test programs to determine this. C++14 compatibility has been extensively tested. In general, if you use a compiler that can build Hana, it can almost certainly build Yap too (I know of no counterexamples). There's also explicit documentation about which compilers are supported: https://tzlaine.github.io/yap/doc/html/boost_yap__proposed_/compiler_support... Zach
On Jan 11, 2017, at 2:53 PM, Zach Laine
wrote: The use of constexpr if is guarded by a macro that is only defined if your compiler supports that feature. The CMake scripts build some test programs to determine this. C++14 compatibility has been extensively tested.
In general, if you use a compiler that can build Hana, it can almost certainly build Yap too (I know of no counterexamples).
There's also explicit documentation about which compilers are supported:
https://tzlaine.github.io/yap/doc/html/boost_yap__proposed_/compiler_support... https://tzlaine.github.io/yap/doc/html/boost_yap__proposed_/compiler_support...
I saw that, which is why I gave it a quick try in the first place. Given that I found no installation instructions and cmake just built examples and tests, I guess I made the wrong assumption about how to use the library. I incorrectly just included your files as if they would work directly. Now a closer look at the code indicates that I have to define the following macro to avoid the constexpr-if statements: BOOST_NO_CONSTEXPR_IF. Now it works fine. Sorry if this should have been obvious, but I am not a user of Hana and have never encountered the need for this macro elsewhere in Boost. Since I assume this will be necessary for (any?) pre-c++17 compiler, I suggest an addition to the “compiler support” page that mentions this. Given that there is no dependence of the library on, for example, cmake-generated configuration files (which there shouldn’t be), I feel this is an important bit of information to give to users. Now at least I can give it a try. Thanks again for the help. Cheers, Brook
On Jan 11, 2017, at 4:34 PM, Brook Milligan
wrote: Now at least I can give it a try. Thanks again for the help.
OK, now that I’m trying it, I have another suggestion. Please include your “customization points” code as an example file in the codebase. I started with that and noted that your “make_terminal(user::number({2.0})” bits are missing a template parameter for the expression. I used boost::yap::expression, which seems to work fine. That might be confusing for some users. This brings up some questions. I recall you stating in the docs that boost::yap::expression<> should be used only for prototyping. The Expression concept is really simple and seems mostly to be a type placeholder for overload resolution. Is that fair? If one is not “supposed” to use boost::yap::expression<>, are there any design considerations / best practices for making a custom expression type? For example, it would seem that a common idiom might be an expression class with a function call operator for evaluation. Does that make sense? Are there general features that useful expression classes “ought” to have or at least should be considered in their design? Or are they really just the bare bones of the concept itself? Can you give some guidelines regarding best practices for all of this? Generally, I feel the documentation is good for a basic understanding and the examples illustrate some very simple use cases. But for anyone wishing to use Yap more deeply, a great deal of extrapolation from those cases will be necessary. It would be really helpful to encapsulate more use cases, common idioms, or best practices in the reference documentation so that practitioners can make more effective use of the library. Thanks again. Cheers, Brook
On Wed, Jan 11, 2017 at 6:21 PM, Brook Milligan
On Jan 11, 2017, at 4:34 PM, Brook Milligan
wrote: Now at least I can give it a try. Thanks again for the help.
OK, now that I’m trying it, I have another suggestion. Please include your “customization points” code as an example file in the codebase.
There are already numerous examples of using the customization points in Yap in the tests and eamples.
I started with that and noted that your “make_terminal(user::number({2.0})” bits are missing a template parameter for the expression. I used boost::yap::expression, which seems to work fine. That might be confusing for some users.
There are two overloaded make_terminal() templates. The one that requires no explicit template parameter already uses boost::yap::expression -- it's not missing in the quoted code above.
This brings up some questions. I recall you stating in the docs that boost::yap::expression<> should be used only for prototyping.
I think this will be true for most users.
The Expression concept is really simple and seems mostly to be a type placeholder for overload resolution. Is that fair?
Not exactly. Expression is meant to be the place where you do the important work for your use case. This may include a set of operator overloads that you care about. Ultimately, using a model of Expression in your code allows you to use all the Yap algorithms. That's the most important idea.
If one is not “supposed” to use boost::yap::expression<>, are there any design considerations / best practices for making a custom expression type? For example, it would seem that a common idiom might be an expression class with a function call operator for evaluation. Does that make sense?
Maybe. In the tarray example, there is this member of tarray, which is an Expression: int operator[] (std::size_t n) const { return boost::yap::evaluate(boost::yap::transform(*this, take_nth{n})); } Since tarray does all its significant work when it is indexed, that is the place where it makes the most sense to put the evaluations. For some other type/template, operator() may make sense too.
Are there general features that useful expression classes “ought” to have or at least should be considered in their design?
Not in the general case.
Or are they really just the bare bones of the concept itself?
Yes.
Can you give some guidelines regarding best practices for all of this?
The best guideline I know of is: make your Expression model do exactly what is required for your use case, and no more.
Generally, I feel the documentation is good for a basic understanding and the examples illustrate some very simple use cases. But for anyone wishing to use Yap more deeply, a great deal of extrapolation from those cases will be necessary. It would be really helpful to encapsulate more use cases, common idioms, or best practices in the reference documentation so that practitioners can make more effective use of the library.
I'm assuming that any reader already needs ETs for some reason. I'm not willing to explain what they are and why they are useful, because there are many such articles online already. If someone needs ETs, they already know what their users' code should look like (or they should figure that out first!), and following the many examples will give them a pretty good idea how to use Yap to get the interfaces they need. Zach
On Jan 12, 2017, at 9:36 AM, Zach Laine
wrote: There are two overloaded make_terminal() templates. The one that requires no explicit template parameter already uses boost::yap::expression -- it's not missing in the quoted code above.
Please document this in the reference documentation for make_terminal(). It seems to include only one of the overloads, hence my confusion. Cheers, Brook
On Thu, Jan 12, 2017 at 10:41 AM, Brook Milligan
On Jan 12, 2017, at 9:36 AM, Zach Laine
wrote: There are two overloaded make_terminal() templates. The one that requires no explicit template parameter already uses boost::yap::expression -- it's not missing in the quoted code above.
Please document this in the reference documentation for make_terminal(). It seems to include only one of the overloads, hence my confusion.
It already is: https://tzlaine.github.io/yap/doc/html/header/boost/yap/algorithm_hpp.html https://tzlaine.github.io/yap/doc/html/header/boost/yap/expression_hpp.html Zach
On Jan 12, 2017, at 9:43 AM, Zach Laine
wrote: It already is:
https://tzlaine.github.io/yap/doc/html/header/boost/yap/algorithm_hpp.html
https://tzlaine.github.io/yap/doc/html/header/boost/yap/expression_hpp.html
OK. Sorry to not remember where all the overloads are defined and which files they must be looked up in. That suggests a need for an index. It also reinforces my suggestion that you include complete examples of all the code used in the documentation. In this case, I started with a _tutorial_ page that was incomplete and had no corresponding complete version. I tried to replicate it and (as a newcomer to this library) got a bit off track (relative to your implied view of what the documentation intended to convey) trying to piece together all the missing bits. Providing complete and correct reference code for the document will only help newcomers like me trying to figure this out. Cheers, Brook
-----Original Message----- From: Boost [mailto:boost-bounces@lists.boost.org] On Behalf Of Brook Milligan Sent: 12 January 2017 16:54 To: boost@lists.boost.org Subject: Re: [boost] Interest in updated expression template library?
On Jan 12, 2017, at 9:43 AM, Zach Laine
wrote: It already is:
https://tzlaine.github.io/yap/doc/html/header/boost/yap/algorithm_hpp.html
https://tzlaine.github.io/yap/doc/html/header/boost/yap/expression_hpp.html
OK. Sorry to not remember where all the overloads are defined and which files they must be looked up in. That suggests a need for an index.
Boost Autoindex and Doxygen, preferably with Doxygen-syntax comments in the code explaining what function do etc, will allow various indexes (function, classes, everything...) to the be built (and rebuilt) automatically. Recommended - from reading my own documentation some years later! Paul --- Paul A. Bristow Prizet Farmhouse Kendal UK LA8 8AB +44 (0) 1539 561830
On Fri, Jan 13, 2017 at 4:12 AM, Paul A. Bristow
Boost Autoindex and Doxygen, preferably with Doxygen-syntax comments in the code explaining what function do etc, will allow various indexes (function, classes, everything...) to the be built (and rebuilt) automatically. Recommended - from reading my own documentation some years later!
Thanks, Paul. How do I turn on Autoindex? I'm using the full Boost documentation toolchain. Zach
-----Original Message----- From: Boost [mailto:boost-bounces@lists.boost.org] On Behalf Of Zach Laine Sent: 13 January 2017 15:29 To: boost@lists.boost.org Subject: Re: [boost] Interest in updated expression template library?
On Fri, Jan 13, 2017 at 4:12 AM, Paul A. Bristow
wrote: Boost Autoindex and Doxygen, preferably with Doxygen-syntax comments in the code explaining what function do etc, will allow various indexes (function, classes, everything...) to the be built (and rebuilt) automatically. Recommended - from reading my own documentation some years later!
Thanks, Paul. How do I turn on Autoindex? I'm using the full Boost documentation toolchain.
RTFM ;-) http://www.boost.org/doc/libs/1_63_0/tools/auto_index/doc/html/index.html You can just get indexes of macro, class, functions, and by adding index terms to your .idx file, you can get a subject index too. To see the autoindex in (big!) action, look at Boost.Math docs. Attached example may help too modular-boost\libs\circular_buffer\doc\jamfile.v2 may help is making the admittedly non-trivial changes to get a full index. You need some items in your .qbk file too (to say which indexes you want). [/Include the indexes (class, function and everything) ] ''' <index type="class_name"> <title>Class Index</title> </index> <index type="function_name"> <title>Function Index</title> </index> <index/> ''' Mail me privately if you need more help. Paul
On Fri, Jan 13, 2017 at 10:09 AM, Paul A. Bristow
-----Original Message----- From: Boost [mailto:boost-bounces@lists.boost.org] On Behalf Of Zach Laine Sent: 13 January 2017 15:29 To: boost@lists.boost.org Subject: Re: [boost] Interest in updated expression template library?
On Fri, Jan 13, 2017 at 4:12 AM, Paul A. Bristow < pbristow@hetp.u-net.com> wrote:
Boost Autoindex and Doxygen, preferably with Doxygen-syntax comments in the code explaining what function do etc, will allow various indexes (function, classes, everything...) to the be built (and
rebuilt)
automatically. Recommended - from reading my own documentation some years later!
Thanks, Paul. How do I turn on Autoindex? I'm using the full Boost documentation toolchain.
RTFM ;-)
http://www.boost.org/doc/libs/1_63_0/tools/auto_index/doc/html/index.html
Ha! I will, now that I know it exists. [snip]
Mail me privately if you need more help.
Thanks, I might take you up on that. For now, this will definitely get me started. Zach
On Fri, Jan 13, 2017 at 10:21 AM, Zach Laine
On Fri, Jan 13, 2017 at 10:09 AM, Paul A. Bristow
wrote:
-----Original Message----- From: Boost [mailto:boost-bounces@lists.boost.org] On Behalf Of Zach Laine Sent: 13 January 2017 15:29 To: boost@lists.boost.org Subject: Re: [boost] Interest in updated expression template library?
On Fri, Jan 13, 2017 at 4:12 AM, Paul A. Bristow < pbristow@hetp.u-net.com> wrote:
Boost Autoindex and Doxygen, preferably with Doxygen-syntax comments
in
the code explaining what function do etc, will allow various indexes (function, classes, everything...) to the be built (and rebuilt) automatically. Recommended - from reading my own documentation some years later!
Thanks, Paul. How do I turn on Autoindex? I'm using the full Boost documentation toolchain.
RTFM ;-)
http://www.boost.org/doc/libs/1_63_0/tools/auto_index/doc/html/index.html
Ha! I will, now that I know it exists.
Thanks for this pointer, Paul. It was relatively painless; now Yap's docs have an index. Zach
On Thu, Jan 12, 2017 at 10:53 AM, Brook Milligan
It also reinforces my suggestion that you include complete examples of all the code used in the documentation. In this case, I started with a _tutorial_ page that was incomplete and had no corresponding complete version. I tried to replicate it and (as a newcomer to this library) got a bit off track (relative to your implied view of what the documentation intended to convey) trying to piece together all the missing bits. Providing complete and correct reference code for the document will only help newcomers like me trying to figure this out.
Ok, I've added an index, explicit sections on evaluations and transformations, and a few other tweaks that you or others have suggested. Thanks for the feedback, Brook. Zach
On Jan 16, 2017, at 10:32 AM, Zach Laine
wrote: Ok, I've added an index, explicit sections on evaluations and transformations, and a few other tweaks that you or others have suggested. Thanks for the feedback, Brook.
Great. Thank you for doing that. In the meantime, I have been playing a bit more with the library and would like to reiterate at least one point from my 2017-01-12 email. As far as I can tell, there is no reason to restrict capturing an expression into expression_wrapper<> by moving it. I made another version that copies and it works fine. I have used that with std::reference_wrapper and a special wrapper that I use to wrap rvalues (i.e., it moves those into either itself or onto the heap so that it preserve the reference semantics yet can be copied). Both worked perfectly, can be stored in std::function<>, etc. It would be nice to support the more general use case of an expression_function<> acting as a reference to another expression when constructed from an lvalue. Then it could be used anywhere as a proxy for evaluating any expression. That seems like a really useful feature. Cheers, Brook
On Mon, Jan 16, 2017 at 12:27 PM, Brook Milligan
In the meantime, I have been playing a bit more with the library and would like to reiterate at least one point from my 2017-01-12 email. As far as I can tell, there is no reason to restrict capturing an expression into expression_wrapper<> by moving it. I made another version that copies and it works fine. I have used that with std::reference_wrapper and a special wrapper that I use to wrap rvalues (i.e., it moves those into either itself or onto the heap so that it preserve the reference semantics yet can be copied). Both worked perfectly, can be stored in std::function<>, etc. It would be nice to support the more general use case of an expression_function<> acting as a reference to another expression when constructed from an lvalue. Then it could be used anywhere as a proxy for evaluating any expression. That seems like a really useful feature.
Thanks for bringing this back up! I totally missed it the first time. The move was perhaps a copy/paste error. Zach
On Wed, Jan 11, 2017 at 5:34 PM, Brook Milligan
Given that I found no installation instructions and cmake just built examples and tests, I guess I made the wrong assumption about how to use the library. I incorrectly just included your files as if they would work directly. Now a closer look at the code indicates that I have to define the following macro to avoid the constexpr-if statements: BOOST_NO_CONSTEXPR_IF. Now it works fine. Sorry if this should have been obvious, but I am not a user of Hana and have never encountered the need for this macro elsewhere in Boost.
Since I assume this will be necessary for (any?) pre-c++17 compiler, I suggest an addition to the “compiler support” page that mentions this. Given that there is no dependence of the library on, for example, cmake-generated configuration files (which there shouldn’t be), I feel this is an important bit of information to give to users.
Excellent point. I'll add a "#define BOOST_NO_CONSTEXPR_IF 0" to config.hpp when it is not otherwise defined.
Now at least I can give it a try. Thanks again for the help.
Happy to help. Zach
participants (7)
-
Brook Milligan
-
Damien Buhl
-
Edward Diener
-
Larry Evans
-
Mathias Gaunard
-
Paul A. Bristow
-
Zach Laine