After being encouraged by AI (and my own intuition on the subject), I am making FAIL take over the "lighter" function of non-divergent error production from the apparently-more-divergent-sounding RAISE.
So... yet another naming musical chairs propagates from that. I guess PANIC is my favorite of the divergent-error-raising options (as opposed to DIE, and of course we have a completely different concept of what THROW is). So what FAIL used to do, PANIC can do now.
Yet internally to the system, panic() has been a funcition to call when it needs the executable to completely shut down.
Easy fix for this is to just call that function crash(), and then panic() can mean "do a Rebol-panic" e.g. don't take the interpreter down, just return control to the REPL (or whatever RESCUE operation).
But curiously... there has been a PANIC native for forcing termination of the interpreter. I could just rename it to CRASH and move along. But it does bring up some interesting design points for there being such a function in Rebol at all.
A CRASH Native Must Take No Evaluative Args
You don't want a situation like having code that is like crash revrese "string" that has a failure on acquiring its arguments, and does not crash the system.
If you hit the point of running CRASH that's the point of no return--it shouldn't be able to jump back up to the REPL with an error.
So CRASH needs to be <endable> in case it's found in a situation like (crash) with no args. If it takes arguments, those arguments should be dialected in such a way that it isn't possible to run usermode code. Because the intention is to get out of the interpreter without causing more damage... like you've noticed some corrupted log file and you want out.
A CRASH Dialect might be able to just output some diagnostic information for you, where you give it variables but none of these get evaluated as expressions which can run function calls...at least not usermode functions.
crash [
"You could have some literal messages..."
checkpoint: <one> ; some literals
machine-status: @status ; inert fetch
]
If you take away the ability to do evaluations, someone is going to try and write:
crash compose [
"This is potentially dangerous, what if the COMPOSE errors?"
checkpoint: (...) ; requesting an evaluation
machine-status: (...)
]
But I'm saying that would exit the intepreter when CRASH saw that you were trying to get it to run more userspace code.
Wily people can work around it:
eval compose:deep [crash [
"Well, aren't you clever..."
checkpoint: (...) ; requesting an evaluation
machine-status: (...)
]]
But if you do this, then you are undermining the defense that is designed to make sure there isn't a failure before the crash.
Anyway, I Thought This Was Interesting
I hadn't really contemplated the importance of designing CRASH to ensure crashing...but that's pretty cool I think.