-
-
Notifications
You must be signed in to change notification settings - Fork 190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Breakup require_generics.hpp into multiple files #1739
Comments
You can also make code shorter and easier to add new requires by using some macros. You can check what I did in |
Agree! |
While you are at this, can you also add some requires for differentiating between sparse and dense matrices? |
@t4c1 I started working on this, can you take a peek at the diff here? It doesn't need a full review, just want a spot check that this seems like the right direction https://github.com/stan-dev/math/compare/cleanup/require_base Essentially it adds macros
It also moves around the docs so the site should be a bit easier to browse. If you can run EDIT*: Had UNARY where I should have had BINARY |
That looks great! Although I have a few questions: |
Why macros and not just more types? And with these macros, what's use going to look like? I worry about maintainability when there are functions X being defined where a search for X in the code fails. |
With complex, we need to be more careful. We've already decided that complex numbers will be treated as scalars. The value type of a What's |
It's for things like
Wanted to get your opinion on how I was going about this before I did all those
Yeah right now I'm defining both those macros in the scalar_type and value_type headers, but if I move some stuff around I can put them in the
Yes I too am not a huge fan of macros. But on this occasion if we don't use them we'll just have a ton of effectively duplicate code. Like say we wanted to add requires for all of the type traits in std. Without the macro we'll have a ton of essentially duplicate code but with the macro we'll just have STAN_ADD_REQUIRE_UNARY(arithmetic, std::is_arithmetic);
STAN_ADD_REQUIRE_UNARY(array, std::is_array); which feels a lot easier to maintain. We can make this safer by also adding a header to undefine the macros at the bottom of each file like #include <stan/math/prim/meta/require_helpers.hpp>
/** \ingroup type_trait
* Defines a static member function type which is defined to be false
* as the primitive scalar types cannot be a stan::math::fvar type.
*/
template <typename T, typename = void>
struct is_fvar : std::false_type {};
/** \addtogroup require_stan_scalar
* @{
*/
STAN_ADD_REQUIRE_UNARY(fvar, is_fvar);
/** @}*/
#include <stan/math/prim/meta/undef_require_helpers.hpp> Then they only exist when processing individual headers which feels safer.
Use will be exactly the same, this is a cleanup that will leave everything fully backwards compatible. The macros just generates the C++ requires aliases. The main thing to me is making sure these are doc'd well, Bob if you have time to check out that branch above and run For doc'ing these, I wouldn't hate having a submodule structure like the below on the lhs of the site
The docs I have right now have some grouping but I think the 3rd level to break them up may be a good idea as well
See above, it's for
Yep fixed it! |
Thanks---that's very clear now. It's cool the expansions show up in the doc. I'd like to stress again that you need to plan for complex in all this, so I think scalar is one level too low to stop---we need to get down to the base real value type. |
Yes def agree! Should there be a
|
Also the only way I can think of doing this nicely without a macro would be to break backwards compatibility with something like // Either T1 or T2 are an eigen type with arithmetic value types
require_t<T1, T2, value_type, require_any, is_eigen, std::is_arithmetic> vs the alternative alias specialization now of require_any_eigen_vt<std::is_arithmetic, T1, T2> |
If we wanted to redesign the requires, we could also use nested structs and a generic negation to do something like:
So that would give us both simple and generic interface. Some examples:
I think this covers most if not all of our use cases. Also it limits code duplication and does not require macros. |
hmm, I do like that. @bob-carpenter how do you feel about the above? I have the macro stuff pretty much ready to rock at this point. The above would break backwards compatibility but it is nice! |
What's breaking backward compatibility? I think the macros are OK for this
purpose. It's the way Boost and Eigen do a lot of this. Was there
something specific you wanted comments on?
- Bob
…On Fri, Mar 20, 2020 at 11:58 AM Steve Bronder ***@***.***> wrote:
hmm, I do like that. @bob-carpenter <https://github.com/bob-carpenter>
how do you feel about the above? I have the macro stuff pretty much ready
to rock at this point. The above would break backwards compatibility but it
is nice!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1739 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAZ2D73ISPUTQGJRDMLNZMLRIOHEFANCNFSM4K2BXQZA>
.
|
I was looking at @t4c1 's comment here But yeah I'm fine with the macros I should have it up today |
Description
After looking at
require_generics.hpp
it's too big and confusing imo. What I'd like to do is take all the stuff in there, break it up so thatrequire_generics.hpp
is just the definitions for the different baserequires_*
, then move the specializations over to each folder the is_* typedef is associated with.Example
is_var.hpp
would look likeCurrent Version:
v3.1.0
The text was updated successfully, but these errors were encountered: