Yes, I think adding a scheduler to the REPL would be require doing continuation passing style evaluation, where each lambda has a context that it has captured responds to instead of one ENV stack for eval. Continuations are often done with lexical closures, so perhaps this is what you’re talking about. Sadly the term closure is a bit overloaded in math and functional programming.
A simpler method may be to have a C function, that is called before or after the REPL function’s call in the main loop, which checks a task/job queue to see if it’s time has come up, and then either runs it directly or drops it into the REPL to run next. The later would allow for “interactive” expressions that require feedback from the user to run, as opposed to just running thunks that update global variables alone.
This would of course require that the REPL has finished running, so infinite or long running programs would block the scheduler in similar ways that garbage collection is blocked, and has to be called manually. This wouldn’t be much of a problem for multi core micros such as the ESP32, which run FreeRTOS, as you could just pin the scheduler to a RTOS Task on another core.
New scheduled tasks could be added to the task queue by passing the time and function to run similar to the above managed state event loop.