I think any illusions of Ren-C being able to bring evaluator "safety" to a fundamentally unsafe language are being stripped away with time. Instead, what's actually happening is that the features are getting laser-calibrated to where an informed programmer can write short, correct, code easily... the right thing is the short thing, not something riddled with edge-case handling.
Clarity and brevity are two fundamental qualities of good writing. I think that applies to programming as well. Also 4 concepts so close (NULL, BLANK!, NOTHING and VOID), make me look for a fundamental problem in the language, or they do not have adequate names.
I do not quite understand the usefulness of these 4 variants but should not there be one, or several but named to make understand to which functionalities of the language they relate (block, value, refinement ...)? Maybe I get it wrong.
Rebol2/Red/R3-Alpha all have basically two concepts: NONE! and UNSET!. NONE! and Ren-C's BLANK! were supposed to be quite similar, just a different name. But eventually NULL took over many of the duties of NONE! as an indicator of "soft failure" from a routine... like when a FIND can't find anything, or a conditional statement doesn't run any branches. BLANK! sticks around as the solution to the problem of neutral placeholders in blocks.
What's happened is that these two ideas (NONE!/UNSET!) have become at least five...depending on how you count, maybe more!
NULL has properties unlike anything in Rebol2. It cannot be put in a BLOCK!. It is a transitional state representing nothing, like how a C null pointer doesn't point to any memory. It is conditionally false if it appears in something like an IF statement, and it is the "soft failure" result indicating something didn't succeed e.g. a FIND that couldn't find what you were looking for, or a loop that BREAKs.
BLANK! is a unit type...e.g. a value of type blank holds no further information (than that it is of type blank). Unlike NULL it's something that can appear in a block, and hence can be used as a placeholder--for instance if a block represents a record structure broken into N-element units, it could represent a missing field. (Update: Values of this type were once conditionally false, but it was later deemed better if they were not.)
Today's idea of VOID -- as promoted by @rgchris -- is as the absence of a value. If you write append [a b c] void you will get [a b c] back (null would have given an error). Among other things, it is result of an IF that does not run its branch.
NOTHING replaces "unset" as the contents of an unset variable (in Ren-C's parlance, variables are unset, not values.). Like null and void (or any other antiforms), it also cannot be put in blocks.
NIHIL is an unstable antiform that can't be stored in a variable at all, but is a transient evaluative product discarded by the evaluator. It's tricky to handle, but gives neat properties to be able to erase evaluations from an execution stream, e.g. so 1 + 2 comment "hi" can synthesize 3.
I think the names have ultimately settled down to work pretty well. Particularly pleasing is that NULL is exposed in the API as C and JavaScript's NULL. That has turned out to be very important.
Rebol2 always had trouble with #[none]-the-unit-value and none-the-word, frequently rendering it as looking like the word:
rebol2>> find [a b c] 'd
== none ; <-- not a WORD!, but a #[none] literal rendered dishonestly
As mentioned, Ren-C's find returns the ~null~ antiform now...which is better.
But reserving plain old _ so it's the literal form for a placeholder...and having it be named BLANK!...has felt pretty good. But we're still in that stretch of time for evaluating decisions for their merit...