A lot of `if`s can be replaced by `if constexpr`
This is based on review by @SteveBronder in my PR https://github.com/stan-dev/math/pull/3157#discussion_r1985559090 but it apparently pertains to many other already implemented distributions as well as functions
When I run the following command
grep -rE if \(!?is_constant stan/math
The output has 1146 lines.
If I understand correctly the value is known at compile time and these could be replaced by if constexpr
similarly:
grep -rE if \(!?include_summand stan/math
has 285 lines.
This is just for illustration, there are others that can be found that can be found by filtering for <.*> or ::value etc. The grep may not find all in case of formatting line breaks. Perhaps this can be done by a more sophisticated regex search and replace through the codebase?
Yes! I have not had time, but what I would really like to do is replace !is_constant and !is_all_constant with a helper variable template like is_autodiff_type_v. Then use constexpr everywhere we have is_constant. So lines like
if (!is_constant_all<T_beta, T_x, T_alpha>::value) {
would be
if constexpr (is_all_autodiff_type_v<T_beta, T_x, T_alpha>)
The helper types would look like
/**
* Checks whether the `scalar_type` of a type is an autodiff type
* @tparam T Any type
*/
template <typename T>
struct is_autodiff_type : is_autodiff<scalar_type_t<T>> {};
template <typename T>
inline constexpr bool is_autodiff_type_v = is_autodiff_type<T>::value;
template <typename... Types>
inline constexpr bool is_all_autodiff_type_v = std::conjunction<is_autodiff_type<Types>...>::value;
Yes! I have not had time, but what I would really like to do is replace
!is_constantand!is_all_constantwith a helper variable template likeis_autodiff_type_v. Then useconstexpreverywhere we haveis_constant. So lines likeif (!is_constant_all<T_beta, T_x, T_alpha>::value) {would be
if constexpr (is_all_autodiff_type_v<T_beta, T_x, T_alpha>)The helper types would look like
/** * Checks whether the `scalar_type` of a type is an autodiff type * @tparam T Any type */ template <typename T> struct is_autodiff_type : is_autodiff<scalar_type_t<T>> {}; template <typename T> inline constexpr bool is_autodiff_type_v = is_autodiff_type<T>::value; template <typename... Types> inline constexpr bool is_all_autodiff_type_v = std::conjunction<is_autodiff_type<Types>...>::value;
Does having this template make it easier to get user declared derivatives and marking parameters as constants, ie don't differentiate? or par variable syntax which possible
It's mostly to prettify the code a bit. It would allow you to do different things for scalars and vectors which can be nice, but otherwise everything should be the same
Solved by https://github.com/stan-dev/math/pull/3240 can be closed