Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CASE statements don't evaluate "body" code for false "conditions" #2245

Closed
Siskin-Bot opened this issue Feb 15, 2020 · 0 comments
Closed

CASE statements don't evaluate "body" code for false "conditions" #2245

Siskin-Bot opened this issue Feb 15, 2020 · 0 comments

Comments

@Siskin-Bot
Copy link
Collaborator

Submitted by: fork

Where an IF statement is laid out as:

    if condition body

CASE statements are laid out roughly as:

case [
    condition1 body1
    condition2 body2
    condition3 body3
]

The rule for CASE is that the bodies don't need to be blocks, or evaluate to one...it can be any expression that produces a value. Moreover, if the expression evaluates to a block, it will be executed in a second evaluation step. (Behavior-wise, the updated behavior of Rebol3's IF brings it into parity.)

>> code: [print "Hello"]
>> case [true code]
Hello

There is however a problem in that Rebol's CASE (in both Rebol2 and R3-Alpha) only uses a DO/NEXT evaluation on the bodies inside a case if the condition is "TRUE?". This leads to a problem that the truth or falsehood of an expression can change the "shape" of the case's execution:

>> condition: true
>> case [condition 10 + 20]
== 30
>> condition: false
>> case [condition 10 + 20]
** Script error: cannot use add on none! value
** Where: + case
** Near: + 20

This is because false conditions skip one item. It needs to skip however many items it takes, which is what would have happened if this had been written as IF CONDITION 10 + 20.


Imported from: CureCode [ Version: r3 master Type: Bug Platform: All Category: Native Reproduce: Always Fixed-in:none ]
Imported from: metaeducation#2245

Comments:

Rebolbot commented on Dec 11, 2015:

Submitted by: Ladislav

The described problem exists also in Rebol 2.


Rebolbot commented on Dec 11, 2015:

Submitted by: Ladislav

Observation:

a: 1
if false (a: 2 [a: 3])
a ; == 2

Does that mean that

a: 1
case [
    false (a: 2 [a: 3]) 
]
a

should yield 2 too?


Rebolbot commented on Jan 3, 2016:

Submitted by: Ladislav

This needs a more complete specification of the desired behaviour. There are two alternatives users like:

  • the first one is to evaluate the code block as it is evaluated when used as an argument of IF,
  • the second one is that the code block must be a literal

The first one is "more general" in the sense that the code in accordance with the second
alternative is also acceptable for the first alternative.


Rebolbot mentioned this issue on Jan 12, 2016:
Should "interstitial" UNSET!s be ignored in "evaluative" contexts?


Rebolbot added the Type.bug on Jan 12, 2016


Hostilefork added Type.bug and Ren.resolved on Nov 14, 2017


Hostilefork commented on Nov 14, 2017:

This is resolved in Ren-C...to the extent that case branches are run through the same function for branch handling that IF--and all branches--use...whatever that is.

(At time of writing that is a somewhat complex rule. Evaluations are not allowed unless they produce a code BLOCK!, but literals are allowed...this prevents double-evaluation unless it's a block. This rule may be kept, relaxed, or possibly only BLOCK! conditions will be allowed and a different construct... CHOOSE, will be used to pick literals instead of the evaluating CASE.)


Hostilefork added the Red.has.this.too on Nov 14, 2017


This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants