Right now we have a couple of dark alleys in the function spec dialect.
"Divergence" (always throws, fails, etc....never returns)
Today's vocabulary word is divergent functions...when a function never returns a result in a "normal" way.
All functions that can FAIL or be THROWN or RETURN'd across have divergence as an option (which is, right now, all functions). But it becomes an issue of what to say when there really is no type a function ever returns...what do you put in the spec?
Lately I've been using just
[return: ]. That might look perfect...by saying there's no types you can return, then any return would generate an error.
But Ren-C is complicated... you've got things like invisible functions, as well as BAD-WORD! isotopes. And NULL which is a bit of a pickle too--I've written about revisiting
<opt> in its own post.
What About Isotopes?
If you say your function returns [bad-word!], that doesn't cover isotope forms.
Right now, there's no type checking on isotopes. Any function can return any isotope right now--they're outside of type checking.
We could narrow it down to just certain isotopes by putting them in the spec as BAD-WORD!s, like [integer! ~none~]...though there's no place to store a list of such isotopes at present :-/
Returning [ any-value!] is already pretty wordy. Having to say [ any-value!] is a hassle. The reasoning I had for letting any function return any isotope was that they're close enough to being errors anyway to a caller...so erroring in the type checking didn't serve that much of a point, for the wordiness.
What About Invisibility?
You can't say plain RETURN these days with no argument unless your function has
<invisible> in the return spec (or if it has
return: <none> which just ignores whatever you return anyway and gives back NONE). That's another weird notational tic.
I just wanted to mention these issues. No great answers right now, so we've just got the mediocre answers. It's working, so...not the biggest priority.