Oldes / Rebol-wishes

Repository for keeping Rebol related wishes out of issues
0 stars 0 forks source link

Make unused refinements FALSE, not NONE #55

Open Siskin-Bot opened 4 years ago

Siskin-Bot commented 4 years ago

Submitted by: fork

Currently, a refinement is in use in the invocation of a function, then the body of the function sees its value as TRUE. If it is not, then it sees it as NONE.

Not being able to take for granted that the refinement is a LOGIC! is frustrating, and has caused me personally several avoidable errors.

@DocKimbel has changed this in Red so that unused refinements are FALSE. Rebol and Red should be able to be in sync on this, and I believe having the refinement always be a LOGIC! is the cleaner invariant.

;; Current behavior

test: func [x /foo y /bar z] [
    print x
    if foo and bar [
        print y
        print z
     ]
]

>> test "Hello"              
Hello
** Script error: and does not allow none! for its value2 argument
** Where: test
** Near: test "Hello"

;; Desired behavior

test: func [x /foo y /bar z] [
    print x
    if foo and bar [
        print y
        print z
    ]
]

>> test "Hello"              
Hello

Imported from: CureCode [ Version: r3 master Type: Wish Platform: All Category: Unspecified Reproduce: Always Fixed-in:none ] Imported from: https://github.com/rebol/rebol-issues/issues/2066

Comments:

Rebolbot commented on Oct 4, 2013:

Submitted by: fork

This has been complicated by me learning that there is nothing special about /local, and that refinements can be used as a method of declaring local variables.

e.g.
    foo: func [value /local x y z] [ ... ]

is rather similar to:

    foo: func [value /x /y /z] [ ... ]

Given this equivalence, it starts to seem a bit weird that these refinements would be initializing x, y, and z to false. It's not a terrible idea considering the more common application is to use the /local convention. It just introduces a new angle to the question.


Rebolbot commented on Oct 4, 2013:

Submitted by: BrianH

That method of quickly declaring local variables is pretty common in user code, particularly experienced user code. We don't do it in mezzanine code, but that is held to a different standard. If this goes through, this practice will likely die out in Rebol 3 code.

There is a lot of code that will continue to work with this proposal, and a lot that will fail in ways that will be difficult to track down. If we do this, it must be documented thoroughly. The conditionally-truthy treatment of APPLY refinement parameters would need to remain - they would be translated to true or false, instead of true or none the way they are now.


Rebolbot commented on Oct 7, 2013:

Submitted by: Gregg

I would like Red and REBOL to be in sync as much as possible. The AND argument is less convincing to me. It's always seemed counter-intuitive to me that refinements used are seen as TRUE. I understand the reason, but expect them to be their actual value or none more than expecting unused refinements to be FALSE.


Rebolbot commented on Oct 7, 2013:

Submitted by: maxim

The culprit here is 'AND... it should simply behave and allow NONE! and switch to normal conditional evaluation, instead of math based bit fields.

I have NEVER needed /refinements to be TRUE/FALSE in over 15 years... because all conditional code reacts equally to none/false. in fact, AND is used very rarely in Rebol.


Rebolbot commented on Oct 15, 2013:

Submitted by: DideC

Funily I have never used 'AND in Rebol. I even did not kow it exists and would have used 'ALL [...] in this usage case.

Changing unset refinment to false instead of none does not hurt me. But I wonder about the code that rely on this specific value !


Rebolbot added the Type.wish on Jan 12, 2016


Hostilefork added Type.wish and Ren.resolved on Jan 24, 2018


Hostilefork commented on Jan 24, 2018:

Ren-C and Red both make unused refinements LOGIC! false. Morever, if one wants to define locals in specs of functions "quickly", Ren-C allows the use of SET-WORD! and they will be unset instead of false at the outset: foo: func [value /x /y /z] [ ... ] => foo: func [value x: y: z:] [ ... ]