-
Notifications
You must be signed in to change notification settings - Fork 432
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
Implement Distribution for Range(Inclusive) #821
Conversation
I agree that this idea is an elegant fix for #744. I have the following comments:
|
I'll add a few more comments:
let distr = 0..20;
rng.sample(distr);
It's certainly an intriguing idea and as @vks says provides a path to deprecate |
In a nutshell, it means we could support things like the example below, which is probably easy to learn for newcomers (and existing users updating to future versions), but has the drawback that we don't have a very good place for documentation. @steveklabnik you must have had plenty of exposure to documentation of things like slice syntax; what's your take on this? use rand::Rng;
let rng = rand::thread_rng();
let c: char = rng.sample(..); // equivalent to rng.gen() and rng.sample(Standard), so redundant
let die_roll = rng.sample(1..=6); // instead of rng.gen_range(1, 7)
let seq = /* some slice/array */;
let i = rng.sample(..seq.len()); // random index; note that we already support seq.choose(&mut rng) |
It's nice to have a consistent API wrt. the non-inclusive case, although if defaulting means the method can be added in the future without breaking semver I have no strong opinion here. If banging out more efficient impls based on the existing ones is straightforward I could have a go.
Agreed, I'm happy to do this if the change is otherwise desired.
I think this is the main drawback. However, that applies equally to
This seems confusing.
What would the type constraint be in this case? Would we need a new trait for types with a lower bound? Bearing in mind that that lower bound is often nonzero, though I'm not sure if there's much of a use case for generating e.g. a value in
I think this is symmetrical with |
It should be easy enough but we probably won't merge this PR soon in any case since 0.7 has seen enough changes; it could make a patch release after 0.7 though. Implementation should consider potential refactoring from deprecating and later removing
That's the best I can think of too, however it doesn't cover everything (e.g.
To reduce confusing it makes sense only to support unsigned ints with
|
Ranges with open endpoints could in general be supported gracefully by the introduction of something like trait Bounded {
const MIN: Self;
const MAX: Self;
} with impls for all the obvious things, but this would be a significant expansion of the scope of the change. |
Rebased and added a little documentation. |
@dhardy I think we can merge this now? In my opinion, only the currently not really used |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, @vks. I'm still not 100% sure on whether we should go this route — it looks reasonable, but:
- If we just remove
gen_range
some users will likely struggle to find its replacement - Keeping
gen_range
too is redundant; I think ultimately we don't want both? - Simply adjusting
gen_range
may be better: users will have to adjust code on update, but will see a clear error message which should make this easy. Additionally this gives us a better place to document usage ofsample_single
vsUniform::new
.
B2: SampleBorrow<Self::X> + Sized | ||
{ | ||
let uniform: Self = UniformSampler::new_inclusive(low, high); | ||
uniform.sample(rng) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may make more sense to convert sample_single
into sample_single_inclusive
, then implement sample_single
via sample_single_inclusive
. At any rate, we should have an optimised implementation of this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
implement sample_single via sample_single_inclusive
Is there a way to do this without introducing an awkward where B2: From<u8> + Sub<B2>
constraint?
This can be addressed with an (arbitrarily long) deprecation period, with a helpful message explaining what to do instead. |
I think we should try adapting |
Isn't this solved by deprecation, as @Ralith suggested? I'm not so worried about documentation, we can make the
I think the biggest drawback of this approach is that it does not allow a deprecation period. |
I mean documentation of the alternative:
True. I'm not hugely worried about this given that an upgrade often requires compile-fixes anyway and replacing I think we should give more weight to arguments about the final design than to arguments about the migration. |
Fair enough. Another advantage of |
To what suboptimal distribution are you referring? This PR doesn't include any new distribution objects, and we need |
I think it does: |
Aren't these more efficient than |
|
Lets make another stab at resolving this in time for the 0.8 release. Goals
Approach one: gen_rangeChange
Approach two: sampleSupport
Variant A is that we keep Variant B is that we deprecate Approach three: a new methodAdd a new method, and possibly deprecate Approach four: rejectWe don't need to satisfy the above goals, though it's certainly desirable. My conclusion after re-reading this is still that adjusting @Ralith are you still interested in this? @cramertj, @TheIronBorn, @hmble also commented on #744. In case of mixed feedback or low feedback I will advertise the question elsewhere. |
There is another approach that is already supported: I agree that approach 1 is preferable, since brevity is the reason for the existence of |
Well, lets go with approach 1 then. To do:
Possibly this list should go in a tracking issue, but it should be okay here. I won't start the work myself immediately, so if someone else wants to, feel free. |
I updated this PR in #1003. However, this implements approach 2. Should I change it to approach 1? |
It seems that you and I seem to agree that 1 is, ultimately, the best option (although I suspect there will be complaints). There haven't been many other people adding their opinion, so lets just go with it. As for budget for breaking changes, 0.7 has been stable for a long time now and for the most part users won't have compelling reasons to need to update, so a few more breaking changes probably aren't a big deal. |
Alright, #1003 now implements approach 1. |
This enables the convenient syntax of
rng.sample(0..10)
, and hence provides a non-disruptive fix to #744. If people think this is a good idea I should update the documentation to mentionsample_single_inclusive
more, but I figured I'd get feedback first.