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

Select "SimpleRand" over generic "Rand" for backwards compatibility #71

Merged
merged 5 commits into from
Dec 14, 2017

Conversation

dhardy
Copy link
Owner

@dhardy dhardy commented Dec 12, 2017

This makes the new Rand basically the same API as the old Rand, but defined via Default. This should make it a drop-in replacement, in theory.

rand-derive will need a bit of tweaking but should be relatively easy.

Copy link

@pitdicker pitdicker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

One test in distributions/default.rs needs to be updated yet to build.

pub fn uniform<T: Rand<Uniform>, R: Rng+?Sized>(rng: &mut R) -> T {
T::rand(rng, Uniform)
pub fn uniform<T, R: Rng+?Sized>(rng: &mut R) -> T where Uniform: Distribution<T> {
Uniform.sample(rng)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before looking at this PR I was just wondering what this function is for. It is not in Rand 0.3.*, right? It seems similar to the new distributions::Rand::rand but only works for integers?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's redundant... IIRC I added it before making the Uniform distribution. It should be removed.

@dhardy
Copy link
Owner Author

dhardy commented Dec 14, 2017

Updated: I removed the uniform, ascii_word_char and codepoint convenience functions in favour of distributions, and fixed the tests.

// Rejection sampling. About 0.2% of numbers with at most
// 21-bits are invalid codepoints (surrogates), so this
// will succeed first go almost every time.
match char::from_u32(rng.next_u32() & CHAR_MASK) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now rejecting about half the results because char <= 0x10_ffff. There is probably a more optimal way, but I would not worry about it for this PR.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very weird. You're right, not something worth trying to solve here (if it even matters much: requiring almost 2 samples on average isn't that slow, and I doubt this distribution is going to get used much outside of "fuzz testing").

Copy link

@pitdicker pitdicker Dec 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rng.next_u32() / 0x11_0000 may do the trick. The division should get optimized to one multiply and shift-right.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to divide by the range again!

I would suggest we use your new range code, but who knows how long it'll be before CTFE is sophisticated enough.

}
}
}

impl Distribution<char> for AsciiWordChar {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was it you who made the comment that this should probably renamed? AlphanumericChar seems to better describe this. Does it make sense to also add a distribution with all printable ASCII characters?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly. Lets leave that for later #73

} else {
i64::rand(rng, Uniform) as isize
Distribution::<i64>::sample(&Uniform, rng) as isize

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to just use next_u32 and next_u64 here and for usize?

Maybe it is also better to change the conditions to test for 64-bit. See the open issue Policy for assumptions about the size of usize. But not a big deal.

if mem::size_of::<isize>() == 8 {
    next_u64() as isize
} else {
    // 32-bit or smaller
    next_u32() as isize
}

@dhardy dhardy merged commit de17011 into master Dec 14, 2017
@dhardy dhardy deleted the simple-rand branch December 14, 2017 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants