December 23, 2022
On Fri, Dec 23, 2022 at 03:21:24PM +0000, jwatson-CO-edu via Digitalmars-d-learn wrote:
> On Friday, 23 December 2022 at 00:00:06 UTC, H. S. Teoh wrote:
[...]
> > My personal guess is that you forgot a `ref` somewhere when you pass the RNG to a function.  Given that due to historical accident std.random uses structs for RNG implementations, and this can sometimes lead to unexpected results when you unintentionally passed an RNG state by value instead of by reference.  One thing to try could be to scan all your function signatures where an RNG is passed, and make sure there's a `ref` on it.
[...]
> I had not passed the RNG in any case, but instead accessed the global RNG from inside any function that uses it.  Is that a potential issue?

Hmm, in that case it's probably not a problem with `ref`.

You probably should give DustMite a shot; from the snippets you've posted so far we haven't found any clues of what might have gone wrong. To narrow down the issue we really need to start from the original code and reduce it to a minimal case.

	https://github.com/CyberShadow/DustMite


T

-- 
Дерево держится корнями, а человек - друзьями.
December 24, 2022

On Friday, 23 December 2022 at 17:53:24 UTC, H. S. Teoh wrote:

>

You probably should give DustMite a shot; from the snippets you've posted so far we haven't found any clues of what might have gone wrong. To narrow down the issue we really need to start from the original code and reduce it to a minimal case.

https://github.com/CyberShadow/DustMite

T

No need, I have ample logging already written into the program.

False alarm everyone, there was a logical error in my code. And not only this, but the error appeared in none of the code I posted, sorry! I was working from a wrong assumption.

I counted calls to my rand01 function and realized that the number of calls was equal to the number of times rand appeared in the file being interpreted, rather than the number of times it should have been evaluated. Then it became clear that the parser was replacing calls to rand with a number, which was displayed repeatedly when a loop was evaluated. I removed rand from the dictionary of substitutions the parser needs to make.

December 24, 2022

On Friday, 23 December 2022 at 07:25:23 UTC, Salih Dincer wrote:

>

You can try using static this.

import std.random;

static this() { } // can try using

Mt19937 rnd;
void init_random() {
  rnd = Random(unpredictableSeed);
}

double rand01() {
    return uniform(0, 1.0, rnd);
}

void main()
{
  init_random();

  struct Atom { double num; }
  alias atom = Atom* function();
  atom[string] primitiveSymbols = [
    "rand" : () => new Atom(rand01)
  ];
  import std.stdio;
  writeln(*primitiveSymbols["rand"]()); // Atom(0.630001)
}

SDB@79

I would still like to learn about this idiom. Can you tell me what it means and when I should use it?

December 24, 2022
On 12/24/22 08:18, jwatson-CO-edu wrote:
> On Friday, 23 December 2022 at 07:25:23 UTC, Salih Dincer wrote:
>> You can try using static this.
>>
>> ```d
>> import std.random;
>>
>> static this() { } // can try using

static this() blocks: executed when a thread a starts (the program has at least one thread: the main thread); so you can put initializations here

~static this() blocks: counterparts of 'static this', executed once for each thread that is terminating

shared static this() blocks: executed once per program (executed by the main thread)

~shared static this() blocks executed once per program when the program is terminating

>>     "rand" : () => new Atom(rand01)

That's the lambda (ananymous function) syntax.

The "rand" key of an associative array is being associated with the function after the ':' character. In the code above, the function creates a new Atom object. So, when the following code is executed:

  primitiveSymbols["rand"]

the same lambda would be returned but the execution of that lambda as the following

  primitiveSymbols["rand"]()

would return a new Atom which would make a call to the rand01() function and get a new random number from the same 'rnd' object.

Ali

December 24, 2022

On Saturday, 24 December 2022 at 16:16:17 UTC, jwatson-CO-edu wrote:

>

Then it became clear that the parser was replacing calls to rand with
a number, which was displayed repeatedly when a loop was evaluated.

Sounds like a case of https://xkcd.com/221/

BTW, you don't need to explicitly initialize unpredictableSeed, because that's how it is already configured dby efault. Setting the seed is useful if you are interested in a specific PRNG algorithm with a specific seed to produce a predictable deterministic pattern.

Another thing is that the current implementation of std.random in Phobos is extremely slow and with some tweaks it can be up to 3x-6x times faster. There's a more advanced mir-random third-party dub package, but I'm not sure whether they have any plans to backport all of their optimizations to Phobos (or whether such contribution would be accepted).

December 24, 2022

On Saturday, 24 December 2022 at 16:42:36 UTC, Siarhei Siamashka wrote:

>

Sounds like a case of https://xkcd.com/221/

BTW, you don't need to explicitly initialize unpredictableSeed,

Another thing is that the current implementation of std.random in Phobos is extremely slow

Even better, I automated the caching of dice rolls to be used later as random numbers! ;P

Thanks for the tips.

December 24, 2022

On Saturday, 24 December 2022 at 16:34:29 UTC, Ali Çehreli wrote:

>

static this() blocks: executed when a thread a starts (the program has at least one thread: the main thread); so you can put initializations here

~static this() blocks: counterparts of 'static this', executed once for each thread that is terminating

shared static this() blocks: executed once per program (executed by the main thread)

~shared static this() blocks executed once per program when the program is terminating

> >
"rand" : () => new Atom(rand01)

That's the lambda (ananymous function) syntax.

The "rand" key of an associative array is being associated with the function after the ':' character. In the code above, the

Ali, your post contained at least 3 things I did not previously know about D; thank you!

And thank you all for helping troubleshoot this issue with my hobby language!

December 24, 2022
On 12/24/22 09:58, jwatson-CO-edu wrote:

>> ~static this()

Should be 'static ~this()'.

>> ~shared static this()

Should be 'shared static ~this()'.

> thank you all

Happy to be helpful...

Ali

December 24, 2022

On Saturday, 24 December 2022 at 17:58:04 UTC, jwatson-CO-edu wrote:

>

Ali, your post contained at least 3 things I did not previously know about D; thank you!

And thank you all for helping troubleshoot this issue with my hobby language!

Thank you for completing me: Tesekkurler hocam in Turkish.

Meanwhile, the compile-time and associative array capabilities are incredible:

alias oT = int;
enum opMap =
[ "×": (oT a, oT b) => a * b,
  "÷": (oT a, oT b) => a / b,
  //...
];

auto doubleAndDivide(oT first, oT second) {
  const foldedDouble = opMap["×"](first, 2);
  return opMap["÷"](foldedDouble, second);
}

void main()
{
  assert(6.doubleAndDivide(3) == 4);
}

Don't you think it's delicious too? It's impossible not to love D.

SDB@79

December 25, 2022

On Saturday, 24 December 2022 at 17:55:11 UTC, jwatson-CO-edu wrote:

>

On Saturday, 24 December 2022 at 16:42:36 UTC, Siarhei Siamashka wrote:

>

Sounds like a case of https://xkcd.com/221/

BTW, you don't need to explicitly initialize unpredictableSeed,

Another thing is that the current implementation of std.random in Phobos is extremely slow

Even better, I automated the caching of dice rolls to be used later as random numbers! ;P

Just in case if you are not joking, caching a certain amount of dice rolls to reuse them later in a circular fashion would make a bad quality pseudorandom number generator (a slightly upgraded version of the xkcd joke). Don't do this. Just use std.random if performance doesn't really matter and you want to avoid an extra library dependency. But if performance does matter and you need hundreds of millions of random numbers for Monte Carlo simulations, fuzz testing or anything else, then consider mir.random.

BTW, a few puzzles from https://adventofcode.com/2022 are trivialized by using randomized bruteforce instead of a more sophisticated algorithm. And having fast random numbers generation helps.