scoping – Module scope confusion


Solving a nasty but small system of differential equations and using EvaluationMonitor to package up and export the solution every 10,000 steps as the kernel tends to crash every so often.

In the process encountered the surprising phenomenon: This version of the code does not export the solution

Module({g,     (* The generic relative value function   
        ...       Other local function declarations *) 
        dump,   (* The Association to package the current solution into *)
        steps   (* The step counter to trigger saving the current solution *)}, 
        (* local function definitions *)
        With({eqns = tables to construct the differential equations},
            With({initconds = tables to construct the initial conditions,
                  vars = tables to construct the list of variables},
                  Quiet(First(NDSolve(Join(initconds, eqns), vars, {t, -(Infinity), t0},
                                       Method   -> {"EquationSimplification"->Solve},
                                       MaxSteps -> (Infinity),
                                       EvaluationMonitor:>{steps++; dynrep = steps;
                                                           If(steps == 10000,
                                                              dump = package the solution; 
                                                              Export(pathname,dump);
                                                              steps = 0;)}))))))

dynrep is global. Evaluating

Dynamic(dynrep)

gave the value steps$22870.

Removing steps from the outer Module and wrapping the call to NDSolve in

Module({steps = 0}, ...)

did the trick. Why? What’s the difference? The term “steps” is not mentioned anywhere in the code except in EvaluationMonitor. Do the With blocks have some impact on the Module scope that I am missing?