Passing Notes Between AI Critiquing Redbol Critique

:person_facepalming:

If you would read anything about isotopes, this argument runs backwards.

Count the falsey forms a beginner has to learn.

In Ren-C: one. IF tests nullity. That's the whole rule. There is no list of falsey types to memorize because the list has a single entry, and "null" is an antiform that can't be in a BLOCK!. So you'll never trip over one in your data.

In Rebol2/Red: two: NONE! and LOGIC! false... plus a rendering ambiguity where the word false and the value #[false] print identically and behave oppositely. The beginner has to distinguish two things the screen actively refuses to distinguish for them:

rebol2>> code: [flag: #[false]]
rebol2>> code
== [flag: false]        ; renders as the word
 
rebol2>> type? second code
== logic!               ; but isn't one
 
rebol2>> word? true
== false                ; and `true` isn't a word either

So whatever the upfront cost of a principled system is, it isn't here. Conditionals are the place where Ren-C has strictly fewer rules.


Why nothing in a BLOCK! is falsey

Why Can't LOGIC (e.g. result of 10 > 20) be in BLOCK!?

Rebol decided everything that looks like a word is a word, and all words are truthy. So true and false stayed ordinary reassignable words, while the actual LOGIC! values were the literals #[true] and #[false] (which the words were bound to via variables)... that then rendered as the words anyway. That conflation has been a thorn for thirty years and people mostly cope by hoping they don't hit it.

In Ren-C the logic antiforms (which ~quasiforms~ evaluate to) simply can't go in a block. You triage first:

>> append [flag:] ~null~
** Error
 
>> append [flag:] boolean ~null~
== [flag: false]

The payoff is the entire argument: nothing that can be in a block is falsey, so the only falsey thing array access can hand you is the null from running off the end. Enumeration becomes trustworthy:

>> block: [a b false c]
>> while [value: try take block] [print mold value]
a
b
false
c

Now the same question in Red. "Is there an element here" and "is the element none" are the same check:

red>> alpha: [1 2 #[none]]
red>> beta: [1 2]
 
red>> none? third alpha
== true
red>> none? third beta
== true

That's not a corner case. That's the standard Rebol idiom value: any [pick block index, <fallback>] being structurally unsound, and it has been broken in every Redbol since 1997.


Where that ended up: IF only tests nullity

Flexible Logic System: Terminology

The system doesn't define true or false at all. They're WORD!s, and yours to use:

>> false
** Error: false is not defined
 
>> 'false
== false                ; it's a word, which is all it ever was

Comparisons return one of two unstorable antiforms: ~null~ (branch inhibitor) or ~okay~ (branch trigger). Neither can be put in a block without triage. You test words with generated predicates that error outside their pair:

true?:  wordtester 'true 'false
yes?:   wordtester 'yes 'no
on?:    wordtester 'on 'off

So if true? var is an actual check rather than an accident of truthiness, and which vocabulary you use is your business—the system has no opinion about yes/no versus on/off. Refinements fall out of the same model: a refinement is null or okay, so if line [...] asks whether it was supplied and can't be confused with someone having passed a false word.


What it costs, since I'd rather say it than have it found

I'm the one who knows where the loopholes are, so let me put them on the table.

The PACK! decay to NULL has edge cases. It does. But note where they land: on people doing deliberate metaprogramming with LIFT/UNLIFT and the antiform/quasiform/quoted mechanics. Which is to say, on the people who have signed up to know how the machinery works.

Negation across word domains is genuinely awkward. not negates nullity, so not 'true doesn't hand you false. You write boolean not true? var, and I still don't have a good name for the YES/NO version. That's a real cost and it's unsettled.

But look at what kind of cost it is. It's notation, not concept, and it lands on deliberate boolean-heavy processing rather than on writing a conditional.

You can't wipe complexity out of a design. You can only push it around to where it isn't biting you during the things you do most. As an Electrical Engineer, I would compare it to noise shaping: the noise doesn't go away, you move it out of the band you care about. The design question is never "is there a cost"--it's who pays it and when. Ren-C puts it on the metaprogrammer, on purpose. Rebol2/Red put it on whoever eventually enumerates a block containing a NONE! or a LOGIC!, which is everyone, silently, later.