On Friday, 23 December 2022 at 00:58:01 UTC, Steven Schveighoffer wrote:
Without the rest of the code, and how random is called, I have a hunch... Are you using threads by any chance?

If, for instance, your calls to rand01 are done in a new thread, that new thread will have a *default* state of Mt19937.
-Steve

Good question, Steve, but I do not intentionally start any threads. Below is the machinery that interprets a for-loop. Do you see anything that would enclose a previous state of the RNG?

```d
specialForms["for"] = function ExprInContext( ExprInContext eINc ){
    // Execute a `for` loop, Default is to increment up by one

    // 1. Parse loop args
Atom*[] loopArgs = flatten_atom_list( second( eINc.expr ) ); // Fetch args string iVarName = loopArgs[0].str; //Get the counter var name
    bool    incrByOne = (loopArgs.length == 3);
    double  loBound   = 0.0;
    double  hiBound   = 0.0;
    double  incr      = 1.0;
    double  i /*---*/ = 0.0;
Atom* loopProg = third( eINc.expr ); // WARNING: TYPE NOT CHECKED
    Atom*   rtnExpr   = null;
    Env*    nuEnv     = null;
    ExprInContext runBlock;


    // Case: Default loop increments by 1.0
    if( incrByOne ){
        loBound = loopArgs[1].num;
        hiBound = loopArgs[2].num;

    // Case: User-specified increment
    }else if(loopArgs.length == 4){
        loBound = loopArgs[1].num;
        incr    = loopArgs[2].num;
        hiBound = loopArgs[3].num;

    // Else: There is a syntax error
    }else  return ExprInContext(
        new Atom( F_Error.SYNTAX, loopArgs.length.to!string ~
" was an incorrect number of loop args. Expected 3 or 4." ),
        eINc.context,
        "`for` got an unexpected number of args"
    );

    // 2. Create a new nested context, bind the counter var
    i     = loBound;
    nuEnv = new Env();
    nuEnv.parent = eINc.context;
    bind_atom( nuEnv, iVarName, new Atom( loBound ) );

    runBlock = ExprInContext(
        loopProg,
        nuEnv,
        "loop body"
    );

    // 3. LOOP:
    while( i <= hiBound ){
        // run block in nested context
        rtnExpr = block_meaning( runBlock ).expr;
        i += incr; // increment
        // Store new counter value so that loop body can access it
        bind_atom( nuEnv, iVarName, new Atom( i ) );
    }

    return ExprInContext(
        rtnExpr,
        eINc.context,
        "loop result"
    );

};
```


Reply via email to