Comments on: UNSET! is not first class
It's important to understand the unset! datatype; otherwise, we run the risk of assuming that it is first class (assignable, passable, returnable) when it's really not intended for that kind of usage!
Unset comes into existence from the simple fact that a value slot in any context must be set to something -- it just can't contain random memory garbage.
The alternative to this method would be to mark the word slot as unset, but that's not a viable solution because we allow direct access to context value spaces with the get, set, values-of and other functions (e.g. in R3 with foreach.)
In addition, there's a benefit to unset! not being first class: it forces errors for appropriate conditions such as usage of uninitialized variables. We want that to happen.
With this in mind, it's not a good idea to allow unset! to pass innocently though most function interfaces. While we do provide a small number of very special exceptions such as get/any or defining it as an accepted type for a lit-word function argument (to make a mild level of console-based optional arguments possible, such as help.)
So, if you find I'm not enthusiastic about extending mezz functions to accept unset! values, you now know why. If you really think such a change is needed, you'll need to write a short explanation for why the exception is required. I'm pretty open minded, but just because we can do something does not mean we should do it.
Note that there are already some exceptions that have been added or left in when they are really helpful. For example: The =, == and =? operators accept unset values for their left argument, as a side-effect of op! evaluation; this exception was left in to make some low-level code easier and faster to write, particularly mezzanine functions like load.
For the most part it's considered a feature for unset values to be caught, so don't lightly push for more exceptions. Those errors are your friends :)
Is there really a reason to expose the unset! type at all?
(I also still like the idea we discussed during the 2004 DevCon about setting "unset" words to errors and making errors word-active; but, it's probably simpler to just never return unset! to the user.)
If this article is about you not willing to make #[unset!] "more first class" than it already is, then I do agree with you (otherwise, the sense of introducing #[unset!] to REBOL would approach zero).
Ironically, #[unset!] is currently first-class enough to be:
* assignable using set/any
* passable to some natives, and to all functions/closures the user designs to accept it
* returnable from some natives (e.g. print) as well as from all functions/closures using exit, return, and even from functions not using either of these
Taking all these properties into account, my opinion is, that functions declaring to handle all REBOL values have to handle #[unset!] too.
Just a clarification, the above contribution means, that e.g. my identical? has to handle it, not that any of natives/mezzanines not handling it should do it too.|
Post a Comment:
You can post a comment here. Keep it on-topic.