Hello Go Kudo,

On Tue, Jun 8, 2021 at 2:33 PM Go Kudo <zeriyo...@gmail.com> wrote:

> Hello iinternals.
>
> There doesn't seem to be much mention of it.
> But, that may be because it has been discussed well in advance.
> Thank you for participating in the discussion.
>

I'm not sure you really addressed https://externals.io/message/114561#114680
? especially this part:

"""
If you pick the second option, then you should consistently separate the
source for both extension-provided RNGs and user-provided ones. I don't
think it makes sense to have extension provided RNGs use a `new
Random(RANDOM_XORSHIFT128PLUS)` interface, while user-provided ones use
`new Random(new SomeRandomSource)`. Going down this route, it should be
`new Random(new XorShift128Plus)`. This is a pure design, which also means
that it's more complicated, and may make simple usages harder (though there
is certainly room for a Random::createDefault() here.)
"""

Now, that might sound like it would take us back to the "full OO" version
(with multiple classes), which was deemed too "user-*un*friendly" by
several people (including me :s),
*but* there are some new ideas to consider, e.g. (for the Random class):

- add a `public static function createDefault(): self` as suggested by
Nikita, or

- change `public function __construct` parameters to e.g.
  `(string $algo = XorShift128Plus::class, ?int $seed = null, mixed
...$extra_args)`
  (that would internally do a `new $algo($seed, ...$extra_args)` to store),
  to be called not as
  `new Random(new UserDefinedRNG($seed_or_null, $foo, $bar))` but as
  `new Random(UserDefinedRNG::class, $seed_or_null, $foo, $bar)`.

Any new opinions (or other ideas)?


> Now, if there is no particular discussion on this, I will try to start the
> voting phase next week.
> Of course, I will contact you separately.
>
> However, I was looking back at the implementation and found only one point
> of concern.
>
> With the current implementation, the results of the following example will
> match.
>
> ```php
> $one = new Random();
> $one->nextInt();
> $two = clone $one;
>
> var_dump($one->nextInt() === $two->nextInt()); // true
> ```
>
> But, this is not true for user implementations.
>
> ```php
> class UserRNG implements RandomNumberGenerator
> {
>     protected int $current = 0;
>
>     public function generate(): int
>     {
>         return ++$this->current;
>     }
> }
>
> $rng = new UserRNG();
> $one = new Random($rng);
> $one->nextInt();
> $two = clone $one;
>
> var_dump($one->nextInt() === $two->nextInt()); // false
> ```
>
> This is because `$rng` is kept as a normal property and is managed by the
> standard PHP mechanism. In other words, it is passed by reference.
>
> This is not consistent with the built-in RNG behavior. However, I don't see
> a problem with this behavior.
> I feel that the standard PHP behavior is preferable to changing the
> userland behavior in a specific way.
>
> I would like to solicit opinions.
>

Couldn't the Random class simply implement `public function __clone():
void` (that would internally do like `$this->algo = clone $this->algo;`)?


>
> Regards,
> Go Kudo
>
> 2021年6月1日(火) 23:28 Go Kudo <zeriyo...@gmail.com>:
>
> > Hello internals.
> > Thanks for continuing to participate in the discussion.
> >
> > I've sorted out the proposal, and finished writing and implementing the
> > RFC.
> > (Funny, I know.) I think it's time to start a discussion.
> >
> > https://wiki.php.net/rfc/rng_extension
> > https://github.com/php/php-src/pull/7079
> >
> > The main changes since last time are as follows:
> >
> > - The ugly RANDOM_USER has been removed.
> > - RandomNumberGenerator interface has been added for user-defined RNGs.
> > - Random class is now final.
> > - Random class now accepts a RandomNumberGenerator interface other than
> > string as the first argument to the constructor.
> > - INI directive has been removed. In 32-bit environments, the result is
> > always truncated.
> >
> > What I'm struggling with now is the behavior when calling nextInt() in a
> > 32-bit environment using a 64-bit RNG. It currently returns a truncated
> > result, which means that the code loses compatibility with the result of
> > running on a 64-bit machine.
> > I was also considering throwing an exception, but which would be
> > preferable?
>

Indeed, a decision has to be made. If you throw an exception, we wouldn't
have the "issue" of different results on 32- vs 64-bit machines, but
XorShift128+ and Secure would be unusable on a 32-bit machine, right?
How do other existing implementations handle this question?

>
> > I would like to answer a few unanswered questions.
> >
> > > What is bias?
> >
> > I' ve confirmed that the bias issue in mt_rand has already been fixed and
> > is no longer a problem.
> >
> > This implementation copies most of it from mt_rand. Therefore, this
> > problem does not exist.
> >
> > Therefore, an equivalent method to mt_getrandmax() is no longer provided.
>

Great!


> >
> > > uint64 & right-shift
> >
> > This is a specification of the RNG implementation. PHP does not have
> > unsigned integers, but RNG handles unsigned integers (to be precise, even
> > the sign bit is random).
> >
> > As mentioned above, PHP does not have unsigned integers, which means that
> > using the results generated by RNGs may cause compatibility problems in
> the
> > future. To avoid this, a 1-bit right shift is always required (similar to
> > mt_rand()).
>

Good to know, thanks.

Regards,

-- 
Guilliam Xavier

Reply via email to