Here's an idea: what if ~true~ and ~false~ are examples of weird isotopic exceptions.
Let's say you could assign them to variables...and fetch them from variables...without erroring:
>> true: ~true~ == ~true~ ; isotope >> false: ~false~ == ~false~ ; isotope >> obj: make object! [y: true, n: false] == make object! [ y: ~true~ n: ~false~ ]
(not being quoted in the assignment indicates they become their isotopic forms.)
This is typically not legal...accessing a WORD! isotope from a variable like true would be an error. But these would be special (like how I'm suggesting isotopic ACTION! would be special in running the action from a word reference...)
Things that tested for truthiness would treat them as expected, considering the ~false~ isotope to be a falsey thing:
>> any [true false] == ~true~ ; isotope >> all [true false] ; null
Being isotopes comes with a constraint...you couldn't put them into blocks. You'd have to ^META them (which would lose their special status, turning them into QUASI-WORD!s...that were truthy.
>> ^ false == ~false~ >> if ^ false [print "Meta false is truthy"] Meta false is truthy
The functions TRUE? and FALSE? could then work on isotopic, non-isotopic, or word forms of TRUE and FALSE...but error if passed other values.
This should work for casual cases of just having variables that hold a true or false state...and gives a good appearance for knowing what you're looking at.
It builds on standard mechanisms, and hence if you need to promote the isotopic state into something that can be represented in a block you can do so... with the caveat that once you do, it will no longer reflect its logical property when used with IF and such.
- That's true for NULL being ^META promoted and put in blocks as well.
And crucially: Since you know isotopes can't be in blocks--and if we say BLANK! is truthy as well--then you'd be guaranteed to visit all the items in a block with code like this:
while [item: try take block] [ print mold item ]
This is easily the best idea so far for dealing with the problem.