Closed masak closed 3 years ago
Positing a slightly different architecture, one in which the same Bel evaluator both presents the REPL prompt and evaluates the user's code, feels like it might make it possible to spawn threads which then don't block the "main" REPL thread from continuing.
I'm here to offer the contrarian view.
Picture a universe in which we have what #204 talks about, a repl
function defined inside of the Bel environment itself:
(def repl ()
(print:bel:read:prompt "> ")
(repl))
This is the best-case scenario in which the REPL itself is defined using only built-ins. Specifically, the bel
call is how we say "and now, evaluate the code". But that would still place that evaluation in a "sub-evaluator" of the current one, by necessity. And that means that all the threads would need to run to completion before control was returned to repl
— the threads on the "current level" are distinct from the threads created inside the bel
call.
I find it difficult to imagine an alternative where this is not so. There is no other action besides bel
that's reasonable to do there in order to evaluate the code.
Closing.
I came back here now to bash OP, but found that my previous comment already said everything I wanted to.
As I discover more and more (realistic) limitations of bel
(eval
), I get more and more disappointed. It does give the power to evaluate arbitrary data as code, but it does it at a slight remove from the "current" evaluator. I'm starting to suspect that this is part of the whole "metacircular" deal... But I'm curious if "run this in a nested evaluator" is really the only option here — is there something fundamentally impossible about "run this in the current evaluator"?
This neatly ties into #395, which I think should not merge, because it would turn bel
into "run this in the current evaluator". Sad but true. On the other hand, I still feel like I haven't fully mapped out the contours of the relationship between the "ambient" evaluator running the Bel code most of the time, and the bel
function in the globals. Only that they cannot possibly be the same thing, because then the metacircularity collapses too hard and turns into actual circularity, looping forever. (How do you define applyf
? By performing all these function calls! Oh, wait.)
As I was experimenting with #348 a bit, I realized for the first time that running something like this:
...actually holds up the execution and doesn't give a new prompt until the thread has finished/"joined". Whether this behavior is correct or not is, I guess, a bit of a philosophical question. But I was slightly surprised, which suggests that maybe it could be incorrect. Even though it makes sense from the point of view of the current architecture.
Positing a slightly different architecture, one in which the same Bel evaluator both presents the REPL prompt and evaluates the user's code, feels like it might make it possible to spawn threads which then don't block the "main" REPL thread from continuing. But even as I write this, it does feel mildly contrived and not at all obvious.
So, hm.