Problem
integer::internal::int_value_index() currently checks all arguments by iterating over f->arity() and calling pars[i] for each argument.
That helper is used inside Expects(...), so in debug builds integer primitives eagerly evaluate every argument before the primitive body runs. This changes the behavior of lazy conditionals such as:
integer::ife
integer::ifl
integer::ifz
For these primitives, only the condition and the selected branch should be evaluated. In debug builds, the current check can evaluate an unused branch, which may be invalid, expensive, or side-effecting.
Expected Behavior
Debug validation should preserve the same lazy evaluation semantics as release builds.
For example, integer::ifz should validate/evaluate:
- argument
0 first
- argument
1 only when the condition is zero
- argument
2 only otherwise
Suggested Fix
Replace the arity-wide helper with one that checks only explicitly requested argument indexes, then call it after branch selection where needed.
Example shape:
[[nodiscard]] inline bool int_value_index(const function::params &pars, std::initializer_list<std::size_t> is)
{
return std::ranges::all_of(is, [&pars](std::size_t i)
{
return pars[i].index() == d_int;
});
}
Then conditionals can validate only the selected branch.
Notes
This is mostly a debug-build correctness issue because Expects(...) is compiled out under NDEBUG, but debug and release should not differ in which lazy branches are evaluated.
Problem
integer::internal::int_value_index()currently checks all arguments by iterating overf->arity()and callingpars[i]for each argument.That helper is used inside
Expects(...), so in debug builds integer primitives eagerly evaluate every argument before the primitive body runs. This changes the behavior of lazy conditionals such as:integer::ifeinteger::iflinteger::ifzFor these primitives, only the condition and the selected branch should be evaluated. In debug builds, the current check can evaluate an unused branch, which may be invalid, expensive, or side-effecting.
Expected Behavior
Debug validation should preserve the same lazy evaluation semantics as release builds.
For example,
integer::ifzshould validate/evaluate:0first1only when the condition is zero2only otherwiseSuggested Fix
Replace the arity-wide helper with one that checks only explicitly requested argument indexes, then call it after branch selection where needed.
Example shape:
Then conditionals can validate only the selected branch.
Notes
This is mostly a debug-build correctness issue because
Expects(...)is compiled out underNDEBUG, but debug and release should not differ in which lazy branches are evaluated.