Discussion: Object-scoped RNG

php.internals

zeriyoshi

5 years ago
Hi internals. I previously proposed an object scope RNG implementation inside. However, the RFC was rejected after a vote. https://wiki.php.net/rfc/object_scope_prng Vote: https://externals.io/message/113888 Discussion: https://externals.io/message/112819 As per my previous proposal, PHP is currently in a very unclear state regarding the random number implementation. So I would like to ask a few questions. - Do you think that PHP needs an object-scoped random number implementation? And why? - If the API in the previous RFC was improved and voted on again, would you be willing to vote for it? - What issues do you think should have been resolved between proposal and ballot in the previous RFC? I would like a variety of opinions. Translated with www.DeepL.com/Translator (free version) Regards, Go Kudo

Unnamed Person

5 years ago
On Tue, May 11, 2021 at 6:58 AM Go Kudo <zeriyoshi@gmail.com> wrote:
> > Hi internals. > > I previously proposed an object scope RNG implementation inside. > However, the RFC was rejected after a vote. > > https://wiki.php.net/rfc/object_scope_prng > > Vote: https://externals.io/message/113888 > Discussion: https://externals.io/message/112819 > > As per my previous proposal, PHP is currently in a very unclear state > regarding the random number implementation. > > So I would like to ask a few questions. > > - Do you think that PHP needs an object-scoped random number > implementation? And why? > - If the API in the previous RFC was improved and voted on again, would you > be willing to vote for it? > - What issues do you think should have been resolved between proposal and > ballot in the previous RFC? > > I would like a variety of opinions. > > Translated with www.DeepL.com/Translator (free version) > > Regards, > Go Kudo
I would like to see an extension that doesn't contain the backwards-compatibility breaking changes in the RFC. Every function, type, and constant should be namespaced according to the extension. For instance, if you want to call it `ext/rng`, then the namespace can be `rng` or `Rng` or `RNG`.No exceptions for now! The previous proposal had namespace things, and un-namespaced things, and breaking changes, and I don't think that made a cohesive proposal. Also, php-src generally doesn't suffix interfaces with the name "Interface". Please provide another name for `RNGInterface`, like `RandomNumberGenerator` or `RNG`.

zeriyoshi

5 years ago
I would like to change the proposal to one based on the original proposal (pecl orng) instead of the confusing RFC proposal. https://github.com/zeriyoshi/php-ext-orng But, I am a bit skeptical about bc-break. It is possible to implement it without destroying the current behavior, but keeping the old implementation may lead to userland implementations that mess up the state of RNGs in the future. I haven't decided whether to include it in the next RFC, but we think we need to deprecate all functions that use RNGs with global state (shuffle(), array_rand(), str_shuffle()) in the future. The API in the rejected RFC was confusing because of my attempt to solve this problem. I've tried to maintain maximum interoperability and usability. Also, I am happy to see that Nikita's rules for namespace assignment to extensions have been approved. I'm going to use the `RNG` namespace. 2021年5月12日(水) 4:46 Levi Morrison <levi.morrison@datadoghq.com>:

Unnamed Person

5 years ago
> Also, I am happy to see that Nikita's rules for namespace assignment to extensions have been approved. I'm going to use the `RNG` namespace.
Just to be clear, you can only use `RNG` as a namespace if the extension is named `ext/rng`. You cannot add namespaced things to `standard` nor `SPL` nor `Core`.

zeriyoshi

5 years ago
Sorry about that. I thought I had indicated that I was getting rid of bc-break and carving out functionality for the `ext/rng` extension in the context of reverting to an ORNG-like class-based implementation. 2021年5月12日(水) 23:51 Levi Morrison <levi.morrison@datadoghq.com>:

Nikita Popov

5 years ago
On Wed, May 12, 2021 at 4:51 PM Levi Morrison via internals < internals@lists.php.net> wrote:
> > Also, I am happy to see that Nikita's rules for namespace assignment to > extensions have been approved. I'm going to use the `RNG` namespace. > > Just to be clear, you can only use `RNG` as a namespace if the > extension is named `ext/rng`. You cannot add namespaced things to > `standard` nor `SPL` nor `Core`. >
This is not correct. The namespace policy RFC specifically and explicitly allows namespacing of components in standard/core, see https://wiki.php.net/rfc/namespaces_in_bundled_extensions#core_standard_spl. Adding something under the RNG\ namespace inside ext/standard is fine (modulo due diligence on the specific choice of namespace name). Regards, Nikita

Unnamed Person

5 years ago
On Wed, May 12, 2021 at 8:58 AM Nikita Popov <nikita.ppv@gmail.com> wrote:
> > On Wed, May 12, 2021 at 4:51 PM Levi Morrison via internals <internals@lists.php.net> wrote: >> >> > Also, I am happy to see that Nikita's rules for namespace assignment to extensions have been approved. I'm going to use the `RNG` namespace. >> >> Just to be clear, you can only use `RNG` as a namespace if the >> extension is named `ext/rng`. You cannot add namespaced things to >> `standard` nor `SPL` nor `Core`. > > > This is not correct. The namespace policy RFC specifically and explicitly allows namespacing of components in standard/core, see https://wiki.php.net/rfc/namespaces_in_bundled_extensions#core_standard_spl. Adding something under the RNG\ namespace inside ext/standard is fine (modulo due diligence on the specific choice of namespace name). > > Regards, > Nikita
It says:
> Because these extensions combine a lot of unrelated or only tangentially related functionality, symbols should not be namespaced under the Core, Standard or Spl namespaces. Instead, these extensions should be considered as a collection of different components, and should be namespaced according to these.
The second sentence is not well defined. I am confident this was discussed as part of the RFC discussion. The understanding I, and at least a few others, took away is that it means these extensions can't namespace anything until another RFC defines that second sentence. In other words, the RFC says you cannot name things in those extensions with the namespace "Core", "Standard", nor "SPL", but it doesn't define what you _can_ use. This is really important. If the RFC author did not have this same consensus then this is a MAJOR problem that needs immediate discussion. Levi Morrison

Rowan Collins

5 years ago
On 12/05/2021 15:39, Go Kudo wrote:
> I haven't decided whether to include it in the next RFC, but we think we > need to deprecate all functions that use RNGs with global state (shuffle(), > array_rand(), str_shuffle()) in the future.
I don't understand why that would be necessary or helpful. The majority of code using those functions does not need repeatable or configurable results, and would not benefit from a more complex API. If you're just deciding which order to show the user some cute pictures of cats, shuffle($array) is much more appropriate than (new RNG\Randomiser(RNG\MT15593))->shuffle($array) or whatever the API ends up looking like. I can however see an argument for deprecating srand/mt_srand: if you want a reproducible pseudo-random sequence, create an object to manage its state; if you don't, leave the engine to manage it for you however it wants. The way the seed was initialised would then be entirely an implementation detail, just like the algorithm, which already changed in 7.0. Regards,
-- Rowan Tommins [IMSoP]

Larry Garfield

5 years ago
On Tue, May 11, 2021, at 7:57 AM, Go Kudo wrote:
> Hi internals. > > I previously proposed an object scope RNG implementation inside. > However, the RFC was rejected after a vote. > > https://wiki.php.net/rfc/object_scope_prng > > Vote: https://externals.io/message/113888 > Discussion: https://externals.io/message/112819 > > As per my previous proposal, PHP is currently in a very unclear state > regarding the random number implementation. > > So I would like to ask a few questions. > > - Do you think that PHP needs an object-scoped random number > implementation? And why?
I don't work in areas that would tend to need such a thing, but other people do so I have no objection to it existing, as long as it's well-designed.
> - If the API in the previous RFC was improved and voted on again, would you > be willing to vote for it?
Yes.
> - What issues do you think should have been resolved between proposal and > ballot in the previous RFC? > > I would like a variety of opinions.
1) Get rid of all of the functions. Object-scoped means... you just have an object with methods on it. That's it. 2) Don't force people to use a subclass with an incomprehensible name. In this case, a single class with a constructor parameter that specifies the algorithm to use is far superior. Possibly that parameter could be an object conforming to an interface if you really want, as long as the default is reasonable so most people never have to use it. 3) Perhaps it should be named RandomSequence or similar? It's not truly generating random numbers. It's generating a repeatable but difficult to produce sequence off of a seed value. That's not the same thing as random_int() et al. So, at first pass, an API could be as simple as (pseudocode): class RandomSequence { public function __construct(int $seed = time(), $algorithm = 'some_default') { ... } public function next(): int { ... } } And that's it. That's nice and simple and predictable to use. 4) As Levi said, we have a new policy document on namespace usage. This is a good first application of it. --Larry Garfield

zeriyoshi

5 years ago
> 1) Get rid of all of the functions. Object-scoped means... you just have
an object with methods on it. That's it. Yes. The previous proposal was a complete mess. We will change it to be based on the ORNG extension that we originally planned. https://github.com/zeriyoshi/php-ext-orng
> 2) Don't force people to use a subclass with an incomprehensible name.
In this case, a single class with a constructor parameter that specifies the algorithm to use is far superior. Possibly that parameter could be an object conforming to an interface if you really want, as long as the default is reasonable so most people never have to use it. Specifying an algorithm by string is indeed simple and easy to use. But when the need to generate a fixed sequence arises, such as in test cases, it becomes difficult to achieve the requirements. I think the classed algorithm approach can solve this problem, although it introduces a bit of complexity.
> 3) Perhaps it should be named RandomSequence or similar? It's not truly
generating random numbers. It's generating a repeatable but difficult to produce sequence off of a seed value. That's not the same thing as random_int() et al. I think you're right. However, in the context of other languages, the name PRNG is used to describe that sequence generator.
> 4) As Levi said, we have a new policy document on namespace usage. This
is a good first application of it. Yes. Thank you Nikita :). 2021年5月12日(水) 6:21 Larry Garfield <larry@garfieldtech.com>:

Christian Schneider

5 years ago
Am 11.05.2021 um 23:20 schrieb Larry Garfield <larry@garfieldtech.com>:
> 3) Perhaps it should be named RandomSequence or similar? It's not truly generating random numbers. It's generating a repeatable but difficult to produce sequence off of a seed value. That's not the same thing as random_int() et al. > > So, at first pass, an API could be as simple as (pseudocode): > > class RandomSequence { > public function __construct(int $seed = time(), $algorithm = 'some_default') { ... } > > public function next(): int { ... } > } > > And that's it. That's nice and simple and predictable to use.
Would the generated values fill the whole int range, i.e. 64 bit on modern systems? And would it make sense to add max and min for the generated values like we have with random_int()? Because mapping arbitrary int values to a specific range is error-prone: Just using modulo leads to bias in the resulting values. - Chris

Alexandru Pătrănescu

5 years ago
On Wed, May 12, 2021 at 6:43 PM Christian Schneider <cschneid@cschneid.com> wrote:
> Am 11.05.2021 um 23:20 schrieb Larry Garfield <larry@garfieldtech.com>: > > 3) Perhaps it should be named RandomSequence or similar? It's not truly > generating random numbers. It's generating a repeatable but difficult to > produce sequence off of a seed value. That's not the same thing as > random_int() et al. > > > > So, at first pass, an API could be as simple as (pseudocode): > > > > class RandomSequence { > > public function __construct(int $seed = time(), $algorithm = > 'some_default') { ... } > > > > public function next(): int { ... } > > } > > > > And that's it. That's nice and simple and predictable to use. > > > Would the generated values fill the whole int range, i.e. 64 bit on modern > systems? > > And would it make sense to add max and min for the generated values like > we have with random_int()? > Because mapping arbitrary int values to a specific range is error-prone: > Just using modulo leads to bias in the resulting values. > >
What I initially proposed is an interface something like: interface RandomSource { public function next($length): string; } where the string returned would be of the specified length and made up of random bytes. I understood that internally, an 32/64 bit int is equivalent to 4 or 8 bytes and that various internal implementations already use ints and not bytes to provide other constructs like shuffle() and array_rand() with random behavior. So I can understand if the function would return an int or an array of ints. Maybe you can contradict me if I understood this wrong. But to fulfill all the need for random, one can further use a wrapper class that can be called RandomGenerator that takes a RandomSource as parameter and have all types of handy methods: generateInt($min = 0, $max = PHP_INT_MAX) generateBoolean() generateNumber() // float between 0 and 1 generateString($length, $characters = '') RandomGenerator would take care of the uniform distribution of values generated based on uniform distribution of source bytes/ints generated. I think that keeping a simple way to generate random information is important so that it can easily be reimplemented in various ways when needed. I like the byte approach more because generateString(4, 'abcd') could consume only 1 byte from the random source. Of course, in this picture, RandomSource implementations can be serializable, if it makes sense. BTW, this name proposal is inspired from this library: https://github.com/paragonie/RandomLib as I'm not good with namings either. Alex