Nicol Bolas wrote (across three messages):
> Be advised: there's already a proposal for improving the seeding of RNGs.
That's good to know. (One issue with encouraging std::random_device though is that std::random_device is not currently required to be in any way nondeterministic. It is allowed to produce the same output on every run of the program.)
> As for the idea, if you're interested in a do-everything RNG class, why bother making the random number engine a template parameter? Why expose the underlying engine at all?
Although it's not part of this proposal draft, in my original version I did provide some typedefs for common generators precisely so that people didn't need to specify an engine as a parameter.
> That seems like an over-complication of the idea. If the goal is to be as simple as Python, then just make it `random_generator`, and have implementations decide on what the underlying engine is.
>
> If you're serious about your random engine and distributions, about the specific details of seeding and so forth, you're not going to use this class. And if just want some randomness, then you don't care about the details. You just want a quick, simple, braindead class that spits out randomness in various ways upon request.
The whole point of this proposal is that it enhances rather than subverts the library we have. Consider this code:
mt19937_gen rng;
double x = rng.variate<std::normal_distribution<double>>(17,3);
it's using the beauty of the library we have while being much easer to use.
The key idea is that it's easy enough for a beginner, but still handy for an expert, and provides a good stepping stone to the facilities that still exist. It's not a dumbing down, it's handy glue to avoid annoying and error-prone boilerplate, boilerplate that's confusing to beginners and a hassle for experts.
> That being said, I see no reason why such a class needs member functions for things we already have algorithms for (or will have, in the case of range-generate). The sooner a C++ programmer is encouraged to look to algorithms, the better. We may want to be as simple as Python, but we should not pretend that C++ is Python.
As I said above and in another post, it's best to see this class as very helpful glue to provide something cohesive.
> `uniform` is not a function that should be an algorithm. If you have an engine, and you want to get a uniform value in a range, we have a whole class for that. Seeding likewise is being looked into for an overhaul. `variate` is not something we need as an algorithm.
EXACTLY! You hit the nail on the head. These are *NOT* algorithms. They are far too simple. They are in fact, basically trivial, they just call out to the classes that we already have, that's the point. It's about ease of use.
My claim is that people don't use the distribution classes because producing a number in the range [0,9] by saying:
std::uniform_int_distribution mydist(0,9)
std::cout << mydist(myengine);
feels cumbersome to a lot of people to the point that people would rather write myengine() % 10 instead. That's also one reason why randint got proposed.
> What's the point of `pick`? Is it *really* that important to have a function that does `*choose`?
Pick is passed a container and gives you an element, because it always gives you an element it makes no sense to return an iterator. Choose is passed two iterators and gives you an iterator.
But yes, pick is trivially implemented as *choose, much as a[i] is trivially *(a+i) and front() and back() on containers are trivial (e.g., foo.front() is *(foo.begin())).
> How do you implement `choose` with ForwardIterators? Does it involve `std::distance` calling, so that it can determine how many items to choose from?
Yes. With a ForwardIterator it'll be O(n) but it would be O(n) expected anyway.
> ForwardIterators can't be subtracted. `sample`'s description seems to rely on that. You probably meant `std::distance`.
Yes, my implementation actually uses std::distance; when Tim turned it into a proposal, I think he tried to simplify the description but this wasn't a valid simplification. Good catch, thanks.
If there is one takeaway here, the point of this class was not to do anything fundamentally new (although it did have to work around the current brokenness in seeding), but to make the facilities we already have easy to use right for beginners and experts alike. The fact that the randint proposal exists is proof enough that as things stand right now is *NOT* good enough in that regard.
Best regards,
M.E.O.