I cannot accept this behavior, which is in Rebol2, R3-Alpha, and Red:
>> x: first [<>]
== <>
>> type? x
== word!
>> y: clear <abc>
== <>
>> type? y
== tag!
The seemingly simple answer of "just make <>
a TAG!" has faced baffling resistance. I've truly never understood the obsession with declaring that <>
somehow has to be "not equals". To me, the "has to be" is empty tag. Not only are empty tags useful to represent in source (empty-tag: copy <>
), even those willing to give that up they will appear at runtime...as the above sample clearly shows.
But a mechanism pioneered to resolve how /
can be a PATH! and yet have a binding like a WORD! can be rewired to apply to <>
as well. String cells have room for a binding they're not using. If you bind all strings of any length to some alias--like -tag-0-, for instance--it can carry that binding wherever it goes. If the tag ever becomes empty and is composed into code, then evaluatively it will run.
It would be mostly indistinguishable from a WORD! for most purposes, but would report itself as a TAG!. This would also allow empty file % to act as modulus, or similar. Empty ISSUE! could be # and you could define that too.
It means that to use the empty value as a value, you have to quote it...which is relatively painless, and people would presumably get used to it, or do make tag! N as one historically would.
>> t: copy <>
** Error, <> is missing its right hand argument
>> t: copy '<>
== <>
>> type of t
== @[tag] ; in the proposed datatype-replacement scheme
Having to quote it is weird, but, that's the way this particular cookie bounces.
I can think of some ways to make it less likely to get bit by having an empty string come to life by stripping bindings on mutation in certain cells. But you can always manually unbind it. Rather than give a "word is unbound" error, it will just decay to inert behavior.
There aren't going to be SET-TAG!s, so you'll have to write -tag-0-: enfix func [...] [...] or similar to re-assign an instance to bind to. But maybe this could have a trick like:
<>/: enfix func [...] [...] ; assign something guaranteed to be a function
<>.: "guaranteed not a function"
set '<> :arbitrary-value ; maybe function, maybe not
Anyway, as with /
, the average user won't be able to tell the difference. It's a compromise, but an important one to get us past a years-long impasse, with a strong set of justifications and fitting into the modern implementation.
Were it just me, I'd have used >< for not equals and avoid all this. But now that the mechanics are all here for other reasons, leveraging it here feels clever. People who don't want their tags to be executable can ask their modules to disable it (by defining the -tag-0- as null) and then they can do things like tag: copy <> without the quote.
With This In Place, We Can Commit to the Tag Design
I'm ready to lay down the law on this, and it is very liberal in opening up TAG! representations
Everything that starts with <
and ends in >
is a TAG!, even with no spaces. That's a finalized decision I can live with and not lament missing <...> "operators", but embrace finding new and innovative ways to apply them as inert signaling labels.
We give up <!-- and --!> from WORD! space, but it's no big loss...and we keep <-- and -->.
The fate of things like abc>def or abc<def (which @Mark-hi has advocated for in the past) is unknown, so that might be a last thinking point.