In another question, I saw the following syntax:
#[unset!]
What is that? If I say type? #[unset!]
in R3, it tells me unset!
, but it doesn't solve the mystery of what #[]
is.
So curious.
In another question, I saw the following syntax:
#[unset!]
What is that? If I say type? #[unset!]
in R3, it tells me unset!
, but it doesn't solve the mystery of what #[]
is.
So curious.
Looks like it's the value-construction syntax for an unset instance, as opposed to the word unset!
:
>> comparison: [unset! #[unset!]]
== [unset! unset!]
>> type? first comparison
== word!
>> type? second comparison
== unset!
>> second comparison
>> first comparison
== unset!
If you're in a programmatic context you could do this with to-unset
, but having a literal notation lets you dodge the reduce
:
>> comparison: reduce ['unset! to-unset none]
== [unset! unset!]
>> second comparison
>> first comparison
== unset!
Looks like they've reserved the #[...] syntax for more of these kinds of constructors.
#[]
is the serialized form for values. Play with MOLD versus MOLD/ALL in the console to get a feel for it.
the #[]
"syntax" is actually not a syntax as such (not legal syntax, if you try it), only special cases of such constructs are "legal", like the #[unset!]
syntax, #[true]
syntax, #[false]
syntax, #[none!]
syntax, or #[datatype! unset!]
syntax.
What is even more interesting, is, what the #[unset!]
value actually is. It happens to be the value every "uninitialized" variable in REBOL has (not in functions, though, function local variables are initialized to #[none!]
), as well as the result of such expressions like print 1
, do []
, ()
, etc.
Regarding the "function local variables ... initialized to #[none!]
" I should add, that only the variables following an "unused refinement" (i.e. the one not used in the actual call) are initialized to #[none!]
together with the refinement variable.
To explain the issue further, the syntactic (Data exchange dialect) difference between true
and #[true]
is, that the former is a word, while the latter is a value of the logic! type. Seen from the semantic (Do dialect) point of view, the difference is smaller, since the (global) word is interpreted as a variable, which happens to refer to the #[true]
value.
Look at the example below:
trance on
>> e: none
Trace: e: (set-word)
Trace: none (word) ;<<<<<
>> e: #[none]
Trace: e: (set-word)
Trace: none (none) ;<<<<<
none is a word in the first one, but in the second one, #[none] is not a word, it is the none's itself. same for other values like unset, true, false.