Skip to content
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

API differences between Uniform and Bernoulli #1211

Closed
Danvil opened this issue Jan 15, 2022 · 6 comments
Closed

API differences between Uniform and Bernoulli #1211

Danvil opened this issue Jan 15, 2022 · 6 comments
Labels
B-API Breakage: API E-question Participation: opinions wanted
Milestone

Comments

@Danvil
Copy link

Danvil commented Jan 15, 2022

Hello,

distributions::Uniform::from panics when the given range is invalid.

In contrast distributions::Bernoulli::new returns an Option object if the given probability is invalid.

It comes to a surprise that seemingly similar functions have different API design. Is there a particular reason for this?

@dhardy dhardy added this to the 0.9 release milestone Jan 15, 2022
@dhardy dhardy added the B-API Breakage: API label Jan 15, 2022
@dhardy
Copy link
Member

dhardy commented Jan 15, 2022

Well, Uniform::new and new_inclusive should probably return a Result — that's something to change for 0.9.

Rng::gen_range should continue to panic on invalid ranges, which fits with other Rng methods better.

But Uniform::from? Implementing From<Range<X>> for Option<Uniform<X>> isn't ergonomic to use, and really from is just a convenience wrapper around new / new_inclusive, so no, these should continue to panic on error.

@Danvil
Copy link
Author

Danvil commented Jan 18, 2022

Would that mean Bernoulli::new or Bernoulli::from_ratio should panic if the probability is invalid?

@dhardy
Copy link
Member

dhardy commented Jan 18, 2022

No; those are construction methods on the type. Uniform::from isn't, but rather an implementation of From...

Returning a Result over panic is a more recent change (see Bernoilli v0.6); there is some possibility of wider usage of Result in the API, but on Uniform::from this is unlikely (we could add TryFrom support in addition however).

This needs further thought/discussion before resolution.

@dhardy dhardy added the E-question Participation: opinions wanted label Jan 18, 2022
@vks vks mentioned this issue Jan 18, 2022
23 tasks
@Danvil
Copy link
Author

Danvil commented Jan 18, 2022

Makes sense. At the moment I see:
Uniform::new: panics -- creates from interval passed as two numbers
Uniform::from: panics -- "converts" from a Range object
Bernoulli::new: Result -- creates from one number
Bernoulli::from_ratio: Result -- creates from two numbers representing a rational number

Three suggested changes:

  • Decide if panic or Result is used for error cases. Then either change Uniform::new to return Result or Bernoulli::new to panic to make the API coherent.
  • Remove Bernoulli::from_ratio as it converts to a single float internally anyway (((f64::from(numerator) / f64::from(denominator)) and just clutters the API.
  • Add Bernoulli::from for num::rational::Ratio to provide a replacement for from_ratio. This function would panic as the From trait requires.

@dhardy
Copy link
Member

dhardy commented Jan 19, 2022

  • We'd prefer ordinary constructors to return a Result: see Bernoulli constructor #799. Somehow we forgot Uniform.
  • I disagree about Bernoulli::from_ratio being just clutter. See uses.
  • num is not an existing dependency of rand, and it would take quite a significant argument to change that (we've had several complaints about too many dependencies). Also, Bernoulli::from(num::rational::Ratio::new(a, b)) is a bit more clunky to use.

@vks
Copy link
Collaborator

vks commented Jan 19, 2022

Somehow we forgot Uniform.

Not really, we did not change the constructors of distributions in rand, because we wanted to avoid breaking changes in rand at the time. In rand_distr, breaking changes are less likely to cause churn, so we only changed the distributions there.

However, I agree we should fix this for Rand 0.9.

vks added a commit to vks/rand that referenced this issue Apr 22, 2022
- This is a breaking change.
- The new error type had to be made public, otherwise `Uniform` could
  not be extended for user-defined types by implementing
  `UniformSampler`.
- `rand_distr` was updated accordingly.
- Also forbid unsafe code for crates where none is used.

Fixes rust-random#1195, rust-random#1211.
vks added a commit to vks/rand that referenced this issue Apr 22, 2022
- This is a breaking change.
- The new error type had to be made public, otherwise `Uniform` could
  not be extended for user-defined types by implementing
  `UniformSampler`.
- `rand_distr` was updated accordingly.
- Also forbid unsafe code for crates where none is used.

Fixes rust-random#1195, rust-random#1211.
dhardy pushed a commit that referenced this issue Feb 6, 2023
* Forbid unsafe code in crates without unsafe code

This helps tools like `cargo geiger`.

* Make `Uniform` constructors return a result

- This is a breaking change.
- The new error type had to be made public, otherwise `Uniform` could
  not be extended for user-defined types by implementing
  `UniformSampler`.
- `rand_distr` was updated accordingly.
- Also forbid unsafe code for crates where none is used.

Fixes #1195, #1211.

* Address review feedback
* Make `sample_single` return a `Result`
* Fix benchmarks
* Small fixes
* Update src/distributions/uniform.rs
@dhardy dhardy closed this as completed Jul 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-API Breakage: API E-question Participation: opinions wanted
Projects
None yet
Development

No branches or pull requests

3 participants