ParametrizedFunction enforces stateful objects: parameters live in a mutable dict, changed in place with update_parameters(), and estimators mutate the user's function on every call. This is not thread-safe, causes hidden side effects, and works against JIT-oriented backends — only the innermost lambdified callable is currently JIT-compiled.
This epic replaces the stateful contract with pure evaluation:
- Parameter values are passed per call —
function(data, parameters) with construction-time defaults, plus a non-mutating with_parameters().
- Estimators become pure and fully JIT-compiled, including their gradients.
- Function objects expose their computational backend, so estimators infer the right transformation machinery instead of taking a redundant
backend= argument.
- Parameter values may be arrays, broadcast against the event axis — e.g. for propagating fit uncertainties over bootstrap parameter samples (see ComPWA/polarimetry).
The steps are tracked as sub-issues.
ParametrizedFunctionenforces stateful objects: parameters live in a mutable dict, changed in place withupdate_parameters(), and estimators mutate the user's function on every call. This is not thread-safe, causes hidden side effects, and works against JIT-oriented backends — only the innermost lambdified callable is currently JIT-compiled.This epic replaces the stateful contract with pure evaluation:
function(data, parameters)with construction-time defaults, plus a non-mutatingwith_parameters().backend=argument.The steps are tracked as sub-issues.