Summary
I would like to discuss whether some ixa APIs that currently accept raw f64 values should instead accept T: Into<f64> / impl Into<f64>.
This would preserve existing f64 call sites while improving ergonomics for users who wrap numeric values in lightweight domain types, such as:
OrderedFloat<f64> for sortable/hashable model times
- validated probability newtypes that guarantee values are in
[0.0, 1.0]
I have not done a full scan of the public API yet, so this issue is mainly to start discussion before digging deeper.
Motivation
Some downstream model code uses typed wrappers around f64 values for scientific/modeling safety and domain clarity.
Two examples that seem relevant to ixa's public interface:
Context::add_plan
Currently this takes a raw f64 time. If a model stores event times as OrderedFloat<f64>, callers need to write:
context.add_plan(time.into_inner(), callback);
Since OrderedFloat<f64> already implements conversion into f64, an Into<f64> boundary could allow:
context.add_plan(time, callback);
ContextRandomExt::sample_bool
Currently this takes a raw f64 probability. If a model uses a validated probability type, callers need to write:
context.sample_bool(MyRng, probability.into());
With an Into<f64> boundary, this could become:
context.sample_bool(MyRng, probability);
Possible API Shape
For example:
fn sample_bool<R, P>(&self, rng_id: R, p: P) -> bool
where
R: RngId + 'static,
R::RngType: Rng,
P: Into<f64>,
{
let p = p.into();
self.sample(rng_id, |rng| rng.random_bool(p))
}
And similarly:
fn add_plan<T>(
&mut self,
time: T,
callback: impl FnOnce(&mut Context) + 'static,
) -> PlanId
where
T: Into<f64>,
{
let time = time.into();
...
}
Exact signatures may need adjustment depending on existing trait structure.
Why This Seems Helpful
This should be backward compatible for existing f64 callers, while making it easier for users to adopt safer domain-specific numeric types.
Potential benefits:
- Better ergonomics for typed model code
- Less repetitive
.into() / .into_inner() at ixa API boundaries
- Encourages scientifically safer modeling patterns, such as validated probabilities
- Keeps validation/domain typing in user code without forcing
ixa to own those domain types
- Should be zero runtime overhead after monomorphization
Caveats
This does not make ixa APIs inherently validate probability or time semantics.
For example, sample_bool(p) would still ultimately rely on rand::random_bool, which checks probability range at runtime and panics for invalid values. Accepting Into<f64> simply lets users pass already-validated probability wrappers directly.
Similarly, accepting Into<f64> for add_plan would not by itself define a stronger model-time type. It would only make wrapper types easier to use at the boundary.
Questions for Discussion
- Do we want this kind of generic numeric boundary in
ixa APIs?
- Are
sample_bool and add_plan good candidates?
- Are there other public APIs where this pattern would be useful?
- Is
Into<f64> the right trait, or would a more explicit trait be preferable?
- Are there any downsides for type inference, docs, or API clarity?
Summary
I would like to discuss whether some
ixaAPIs that currently accept rawf64values should instead acceptT: Into<f64>/impl Into<f64>.This would preserve existing
f64call sites while improving ergonomics for users who wrap numeric values in lightweight domain types, such as:OrderedFloat<f64>for sortable/hashable model times[0.0, 1.0]I have not done a full scan of the public API yet, so this issue is mainly to start discussion before digging deeper.
Motivation
Some downstream model code uses typed wrappers around
f64values for scientific/modeling safety and domain clarity.Two examples that seem relevant to
ixa's public interface:Context::add_planCurrently this takes a raw
f64time. If a model stores event times asOrderedFloat<f64>, callers need to write:Since
OrderedFloat<f64>already implements conversion intof64, anInto<f64>boundary could allow:ContextRandomExt::sample_boolCurrently this takes a raw
f64probability. If a model uses a validated probability type, callers need to write:With an
Into<f64>boundary, this could become:Possible API Shape
For example:
And similarly:
Exact signatures may need adjustment depending on existing trait structure.
Why This Seems Helpful
This should be backward compatible for existing
f64callers, while making it easier for users to adopt safer domain-specific numeric types.Potential benefits:
.into()/.into_inner()atixaAPI boundariesixato own those domain typesCaveats
This does not make
ixaAPIs inherently validate probability or time semantics.For example,
sample_bool(p)would still ultimately rely onrand::random_bool, which checks probability range at runtime and panics for invalid values. AcceptingInto<f64>simply lets users pass already-validated probability wrappers directly.Similarly, accepting
Into<f64>foradd_planwould not by itself define a stronger model-time type. It would only make wrapper types easier to use at the boundary.Questions for Discussion
ixaAPIs?sample_boolandadd_plangood candidates?Into<f64>the right trait, or would a more explicit trait be preferable?