[m-rev.] time additions (was Re: for review: Add random.init/3)

Julien Fischer jfischer at opturion.com
Sun May 29 19:55:29 AEST 2016


Hi Mark,

On Sun, 29 May 2016, Mark Brown wrote:

> On Sat, May 28, 2016 at 3:15 PM, Julien Fischer <jfischer at opturion.com> wrote:
>> On Sat, 28 May 2016, Mark Brown wrote:
>>> On Sat, May 28, 2016 at 12:50 PM, Julien Fischer <jfischer at opturion.com>
>>> wrote:
>>>> To a large extent; the lack of support for constructor classes in the
>>>> type class system has also meant that it isn't quite expressive enough
>>>> to make their wholesale addition to the standard library worth it.
>>>
>>>
>>> Providing an interface to random number generators is not a wholesale
>>> addition, though. Is there any proposal for such an interface that
>>> actually involves constructor classes? (Or is this more of an excuse
>>> than a reason ;-))
>>
>>
>> Ok, I wasn't terribly clear there :-(  What I meant is that the lack
>> of type classes throughout the library _in general_ is largely due to
>> the lack of constructor classes -- we cannot, for example, provide
>> classes that abstract the various container types without them.
>> In the specific case of a RNGs there is no problem with adding new
>> classes (or indeed in any other case that doesn't require constructor
>> classes).
>
> That was clear enough, but I don't agree with the adverb "largely".
> The problem I always seem to hit is the even older chestnut regarding
> restrictions on the arguments of typeclass instances. Sometimes you
> can work around these, but often that's where I get stuck.
>
> IIRC, you removed some of these restrictions a few years ago, but I
> don't remember the details. The remaining restrictions are still a
> problem, though.

I removed the restriction on duplicate type variables in instance heads a while
back.  Of the remaining restrictions the one that causes me the most problems
is the one that says some of the arguments in the instance head cannot be type
variables.  This affects, among other things, the composibility of instances of
the stream type classes.  (That's also one of the ones you bump into below.)

> On Sat, May 28, 2016 at 12:50 PM, Julien Fischer <jfischer at opturion.com> wrote:
>> This kind of thing has been discussed several times in the past
>> (see:
>> <http://lists.mercurylang.org/archives/users/2007-February/004331.html>
>> for example.)
>
> I don't like these proposals. As Doug Auclair pointed out, the method
> to seed the generator doesn't belong together with the method to
> generate numbers, because you usually don't use these methods in the
> same parts of the program. Exactly how a generator is initialised
> depends very much on the generator - some generators don't even have
> seeds (e.g., one that reads from a file).

I'm not advocating we adopt the proposal from 2007, just using it as an example
of "this kind of thing".  (I suggest elsewhere in this thread that the random
module from the C++ stdlib or Boost.Random are more the direction in which we
should be heading.)

I don't think that is a particularly onerous requirement for all generators to
have seed type, in the example you mention where we read values from a file,
that type of the seed would just be the "unit" type.

> I also don't like putting the burden of managing the precision of the
> generators on the caller, by having a method like max/3. 
> It's better to have those generators that need such management to handle it
> in their own way, and require all generators to produce a full word of random
> bits.

Sure, I would consider the above still up for discussion.

> As an aside, note that the tausworthe3 generator mentioned (which I
> think is the one from extras/gator) fails almost all of the dieharder
> tests on 64-bit platforms, which is a slight bug. Looking at the code,
> it seems that 64-bit platforms would need to truncate values to 32
> bits after some of the left-shift operations, since this is what would
> happen on on a 32-bit platform.

That's not surprising -- the original author of that implementation
wasn't working on a 64-bit machine when he wrote it.

>> My current thinking on this is that all random number generators should
>> be required to have a unique state value threaded through their
>> operations.
>
> Agreed. Even when generators don't actually need the uniqueness, it's
> good to stop users accidentally copying a generator when they don't
> mean to. Making it unique will force them to explicitly duplicate a
> generator if that's what they want to do.
>
>> That value would be required to be an instance of the
>> standard library's store/1 type class
>
> It would certainly be very nice to do this. But here's what happens when I try:
>
>    % Random number generator G with store S
> :- typeclass random(G, S) where [
>    pred random(G::in, int::out, S::di, S::uo) is det
> ].

What I meant was that store should be a superclass of random:

     :- typeclass random(G, S) <= store(S) where ...

>    % This is the instance I want to write.
> :- instance random(generic_mutvar(T, S), S) <= store(S).
>
> But it's not accepted because the second argument is a variable.

And here we start crashing into problems ... :-(

> I could instead try something like:
>
> :- instance random(io_mutvar(T), io) where ...
> :- instance random(store_mutvar(T, S), store(S)) where ...
>
> But these can't be used in code which is already generic in the store
> that is being threaded through. You need to write the same code out
> twice, too.

Neither of those should work according to our current rules for instance heads.
After you expand all the equivalence types, you would have:

     :- instance random(generic_mutvar(T, io), io) where ...
     :- instance random(generic_mutvar(T, store(S)), store(S)) where ...

and both of those do not meet the requirement that each argument "must be
either a type with no arguments, or a polymorphic type whose arguments are all
type variables".

> Anyone have any ideas?

I don't think the above is a showstopper, for one thing the RNG "handle" type
is unlikely to actually *be* a mutvar, although it may contain them.  This is
actually fairly similar to instance of the stream type classes and we manage to
(mostly) muddle through with them alright.

>> (i.e. the current RNG interface,
>> such as it is, would be pretty much entirely thrown away).
>
> No objections from me.
>
> Does your earlier removal of some of the restrictions help with any of
> the above?

Not enough, unfortunately.

Julien.


More information about the reviews mailing list