-
-
Notifications
You must be signed in to change notification settings - Fork 1
Simplify trait BlockRngCore and rename to Generator #26
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
base: master
Are you sure you want to change the base?
Conversation
|
If |
|
This doesn't stop us removing the |
|
I'm inclined to go this path (this PR and #24 but keeping the The thing I like least is that |
| /// The result type. | ||
| /// | ||
| /// This could be a simple word like `u64` or an array like `[u32; 16]`. | ||
| type Result; |
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.
Should this be renamed? Most of the std::ops traits have an Output associated type, so that may be the more logical name.
| /// } | ||
| /// } | ||
| /// ``` | ||
| fn generate(&mut self, result: &mut Self::Result); |
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.
Generating by-reference has two limitations:
- Using it requires first constructing a "default" instance. Since we don't even require
Result: Default, this is only usable when theResulttype is known or otherwise bounded. In practice this seems fine for our use-cases, but it could be an issue. - Using it to generate small,
Copytypes is unergonomic and dependent on inlining for good performance.
Alternative 1: return Self::Result by value. This is easier to use. For chacha20 (uses 2048-bit output blocks) it may be dependent on inlining optimisations for performance. (This type of optimisation is commonly relied on by constructors in Rust.)
Alternative 2: have both fns. Over-complex.
I don't think it makes sense to have both the block traits and #24. We should either use the block traits and a generic block wrapper around them to implement My initial intent for introducing the block trait was simplification of implementation code by using type aliases (i.e. The block trait code results in a significant amount of useless boilerplate, both in Since you haven't provided any additional motivation for this PR except |
|
Your arguments seem to be against keeping the
Motivation roughly coincides with direct utility of generator "cores". (There might be other motivations but I believe they are grossly limited by the lack of specialization, for now at least.) A search for
Oh, it will work. I wonder whether there will be a noticeable performance hit; possibly not much since branch predictors are quite good. But if I remember correctly the current design was benchmark driven. |
CHANGELOG.mdentrySummary
Removes assoc. type
BlockRngCore::Itemand removes bounds onResults.Renames to
Generator.BlockRng{,64}is now more restrictive: e.g. it can't supportResult = Vec<u32>. I think we could support the same bounds as previously (AsRef<[u32]> + Default), but we shouldn't. Anyway, #24 makes this irrelevant.Motivation
#24 and the
rngsPR made me realise that we do want a "generator" trait, especially forReseedingRng. Hence e.g.Hc128Coreshould remain public.I also realised that we can use the same
BlockRngcode over a much simpler trait.Missing parts
Documentation
Obviously documentation needs some work. Better to wait until after #24 though (which will need to be rebased over this — shouldn't be too hard).
Provided impls
I'd also love to provide impls like this:
Sadly there's "one little issue": conflicting trait implementations. (Do I want to go on a rant about how Specialization/other-solutions-to-conflicting-trait-impls has been Rust's biggest missing feature for over a decade? Yes, but also no. Currently we can't even do this.)
So we work around that by having RNG crates impl both traits. (We could provide a set of macros to help, but probably doc-examples that can be copied are the better solution: there won't be much code anyway provided we keep the existing helper methods.)
Of course, RNG crates could still implement only the
RngCoretrait.Questions
Should word-generators implement the
Generatortrait? In a way it's a nice interface, though we don't have any immediate applications. Perhaps combined with specialization it could lead to some optimizations (e.g. rust-random/rand#1286 is an example where the sample-size arguably should depend on the generator).Drawbacks
rand_corehas a lot of traits:RngCore,CryptoRngGenerator,CryptoGeneratorTryRngCore,TryCryptoRngSeedableRngIs this too many?