Jump to page: 1 2
Thread overview
Re: Experimental approach to reference-type random number generators
Sep 01, 2013
bearophile
Sep 01, 2013
bearophile
Aug 30, 2013
Dmitry Olshansky
Aug 30, 2013
Dmitry Olshansky
Aug 30, 2013
monarch_dodra
Aug 30, 2013
Dmitry Olshansky
Aug 30, 2013
monarch_dodra
August 24, 2013
On 24/08/13 20:35, Joseph Rushton Wakeling wrote:
> Apart from that, {enj, destr}oy.  Does this look like a valid route to a
> next-gen std.random? :-)

I should offer a vote of thanks to monarch_dodra, who referred me to ByLine as an example of a reference range (from where I got the idea to use RefCounted), and to John Colvin and Artur Skawina who pointed me at some useful info on wrapping arbitrary structs.

August 24, 2013
On 24/08/13 20:35, Joseph Rushton Wakeling wrote:
> I do have one specific query

Actually, two.  Lines 448-457 of the second codepad paste have this unittest, with the last line commented out:


    // Check .save works
    foreach (Type; TypeTuple!(MinstdRand0, MinstdRand))
    {
        auto rnd1 = Type(unpredictableSeed);
        auto rnd2 = rnd1.save;
        //assert(rnd1 == rnd2);
        // Enable next test when RNGs are reference types
        version(none) { assert(rnd1 !is rnd2); }
        //assert(rnd1.take(100).array() == rnd2.take(100).array());
    }

If the last assert is uncommented,

    assert(rnd1.take(100).array() == rnd2.take(100).array());

... then running the unittests results in the following error:

    /opt/dmd/include/d2/std/array.d(37): Error: variable std.array.array!(Take!(RandomGenerator!(LinearCongruentialEngine!(uint, 16807, 0, 2147483647)))).array.r has scoped destruction, cannot build closure

This is rather worrying and I'm concerned that this could be a fundamental flaw in the whole design.  Can anyone advise on how to fix it?
August 30, 2013
24-Aug-2013 22:48, Joseph Rushton Wakeling пишет:
> On 24/08/13 20:35, Joseph Rushton Wakeling wrote:
>> I do have one specific query
>
> Actually, two.  Lines 448-457 of the second codepad paste have this
> unittest, with the last line commented out:
>
>
>      // Check .save works
>      foreach (Type; TypeTuple!(MinstdRand0, MinstdRand))
>      {
>          auto rnd1 = Type(unpredictableSeed);
>          auto rnd2 = rnd1.save;
>          //assert(rnd1 == rnd2);
>          // Enable next test when RNGs are reference types
>          version(none) { assert(rnd1 !is rnd2); }
>          //assert(rnd1.take(100).array() == rnd2.take(100).array());
>      }
>
> If the last assert is uncommented,
>
>      assert(rnd1.take(100).array() == rnd2.take(100).array());
>
> ... then running the unittests results in the following error:
>
>      /opt/dmd/include/d2/std/array.d(37): Error: variable
> std.array.array!(Take!(RandomGenerator!(LinearCongruentialEngine!(uint,
> 16807, 0, 2147483647)))).array.r has scoped destruction, cannot build
> closure

Now I'm in the same boat in the midst of wrok of applying new std.uni facilities to std.regex. As soon as std.array.array started using trusted lambda internally it doesn't accept any range with destructor.

This is simply not acceptable, I'll put a minimized test-case in Bugzilla if nobody beats me to it.

>
> This is rather worrying and I'm concerned that this could be a
> fundamental flaw in the whole design.  Can anyone advise on how to fix it?

It seems a fundamental bug in closures. They have to work somehow with these structs esp as in this case there need not to allocate GC closure (no references escapes scope of std.array.array).

-- 
Dmitry Olshansky
August 30, 2013
On 30/08/13 15:32, Dmitry Olshansky wrote:
> This is simply not acceptable, I'll put a minimized test-case in Bugzilla if
> nobody beats me to it.

Please do, I think you will state the case better than me :-)

> It seems a fundamental bug in closures. They have to work somehow with these
> structs esp as in this case there need not to allocate GC closure (no references
> escapes scope of std.array.array).

Oddly enough that's a relief, because it means that the approach I've outlined to RNGs probably isn't fundamentally flawed.

August 30, 2013
On Friday, 30 August 2013 at 13:32:31 UTC, Dmitry Olshansky wrote:
> Now I'm in the same boat in the midst of wrok of applying new std.uni facilities to std.regex. As soon as std.array.array started using trusted lambda internally it doesn't accept any range with destructor.

Is the bug specific to trusted lambdas? I mean, would simply using a named function work around the problem?

If so, then we should simply patch array immediately, while waiting for a lambda improvement. Having a broken "std.array.array" is problematic for everyone...
August 30, 2013
30-Aug-2013 17:38, Joseph Rushton Wakeling пишет:
> On 30/08/13 15:32, Dmitry Olshansky wrote:
>> This is simply not acceptable, I'll put a minimized test-case in
>> Bugzilla if
>> nobody beats me to it.
>
> Please do, I think you will state the case better than me :-)
>

Not very colorful but with minimal test-case ...
http://d.puremagic.com/issues/show_bug.cgi?id=10928



-- 
Dmitry Olshansky
August 30, 2013
On Friday, 30 August 2013 at 15:18:09 UTC, Dmitry Olshansky wrote:
> 30-Aug-2013 17:38, Joseph Rushton Wakeling пишет:
>> On 30/08/13 15:32, Dmitry Olshansky wrote:
>>> This is simply not acceptable, I'll put a minimized test-case in
>>> Bugzilla if
>>> nobody beats me to it.
>>
>> Please do, I think you will state the case better than me :-)
>>
>
> Not very colorful but with minimal test-case ...
> http://d.puremagic.com/issues/show_bug.cgi?id=10928

I took a look at your bug report. This works:

//----
struct D
{
    int x;
    ~this()
    {

    }
}

void foo(D bar)
{
    void do_it(){ bar.x++; }
    do_it();
}

void main()
{
    foo(D.init);
}
//----

So while lambdas remain broken we can easily work around the problem in std.array.array.

If you'd care to file a pull request, I can review it double quick.
August 30, 2013
30-Aug-2013 19:31, monarch_dodra пишет:
> On Friday, 30 August 2013 at 15:18:09 UTC, Dmitry Olshansky wrote:
>> 30-Aug-2013 17:38, Joseph Rushton Wakeling пишет:
>>> On 30/08/13 15:32, Dmitry Olshansky wrote:
>>>> This is simply not acceptable, I'll put a minimized test-case in
>>>> Bugzilla if
>>>> nobody beats me to it.
>>>
>>> Please do, I think you will state the case better than me :-)
>>>
>>
>> Not very colorful but with minimal test-case ...
>> http://d.puremagic.com/issues/show_bug.cgi?id=10928
>
> I took a look at your bug report. This works:
>
> //----
> struct D
> {
>      int x;
>      ~this()
>      {
>
>      }
> }
>
> void foo(D bar)
> {
>      void do_it(){ bar.x++; }
>      do_it();
> }
>
> void main()
> {
>      foo(D.init);
> }
> //----
>
> So while lambdas remain broken we can easily work around the problem in
> std.array.array.
>
> If you'd care to file a pull request, I can review it double quick.

Got it:
https://github.com/D-Programming-Language/phobos/pull/1535

-- 
Dmitry Olshansky
September 01, 2013
See also this idea (and API problem):
http://d.puremagic.com/issues/show_bug.cgi?id=5849

Bye,
bearophile
September 01, 2013
On 01/09/13 14:21, bearophile wrote:
> See also this idea (and API problem):
> http://d.puremagic.com/issues/show_bug.cgi?id=5849

On dice(): I think this is one case of what is in practice a random number _distribution_, akin to uniform().

My own instinct is that as much as possible, random number distributions should come in two forms -- functions, and ranges.  So, it should be possible to go,

    foreach(_; 0 .. 10)
    {
        writeln(uniform(0.0, 1.0));
        writeln(dice(10, 5, 7));
    }

but equally well to go,

    auto uniDist = uniformDistribution(0.0, 1.0);
    auto biasedDice = diceDistribution(10, 5, 7);
    foreach(u, d; lockstep(uniDist, biasedDice).take(10))
    {
        writeln(u);
        writeln(d);
    }

(I'm sure you can find something to improve in how I've written the second example, but you get the idea of how the distributions could behave:-)
« First   ‹ Prev
1 2