doc icon indicating copy to clipboard operation
doc copied to clipboard

`else` will not topicalize to the value of the prior false `if` condition

Open khoguan opened this issue 2 years ago • 5 comments

https://docs.raku.org/language/control.html#with_orwith_without says that

As with the other chainable constructs, an else completing a with/if..orwith/elsif chain will itself topicalize to the value of the prior (failed) condition's topic (either the topic of with or the final orwith or elsif).

Rakudo v2023.02. on MoarVM v2023.02 shows different behaviors between else after if and else after with.

if 0 { say 0 } else { say $_ } # (Any) if 0 { say 0 } else -> $a { say $a } # 0 if '' { say 'empty str' } elsif 0 { say 0 } else { say $_ } # (Any) if '' { say 'empty str' } elsif 0 { say 0 } else -> $a { say $a } # 0 with Failure { say 'fail' } else { say $_ } # (Failure) with Failure { say 'fail' } else -> $a { say $a } # (Failure)

Is this the doc's bug or the rakudo's bug?

khoguan avatar Mar 17 '23 09:03 khoguan

This is certainly not a Rakudo bug but a matter of consistency. if is not supposed to topicalize unless its block has a parameter. Thus, else follows the rule.

Contrary, with topicalize always, thus its else does so too.

vrurg avatar Mar 17 '23 15:03 vrurg

The documentation already mentions

  1. "The with statement is like if, but tests for definedness rather than truth, and it topicalizes on the condition, much like given"
  2. "The if does not change the topic ($_) by default. In order to access the value which the conditional expression produced, you have to ask for it more strongly"
    • i.e., with an explicit parameter ("strongly" might need rephrasing here for clarity); see here.

Would it be worth adding explicit mention of how topicalisation here relates to else branches?

cfa avatar Mar 17 '23 15:03 cfa

I agree, though, that the documentation should be revised in order to express ideas more clearly.

The with statement is like if, but tests for definedness rather than truth, and it topicalizes on the condition, much like given:

As vrurg said, this is on point - it rightfully implies that if in itself does not topicalize (unlike given and with).

You may intermix if-based and with-based clauses.

I think this is where the confusion is coming from, both for the untrained eye and the phrasing of the documentation. A few made-up snippets:

if 0 { .say } orwith Nil { .say } else { .say } # third clause runs - Nil
if 0 { .say } orwith Nil { .say } elsif 12 { .say } else { .say } # third clause runs - (Any)
if 0 { .say } orwith Nil { .say } elsif 0 { .say } else { .say } # fourth clause runs - (Any)

It seems that elsif is much like an if in this regard - it undoes the topicalization, and this "undone topic" is then taken over by the else - much like for usual if-else.

As with the other chainable constructs, an else completing a with/if..orwith/elsif chain will itself topicalize to the value of the prior (failed) condition's topic (either the topic of with or the final orwith or elsif).

If my hypothesis is right, "elsif" simply shouldn't be named at the end. It doesn't have a topic in the same sense with and orwith have.

I'm thinking about improvements... if the elsif behavior is really the intended one, it would be good to say it explicitly that it unsets the topic, and that the code block of else keeps the topic that the preceding conditional sets up. Also, perhaps it's good to be loud and clear about the conditions themselves being unaffected by the whole thing.

2colours avatar Mar 17 '23 15:03 2colours

with topicalize always

With, hmm, given, er, using a 2022 Rakudo (and, I'm guessing, a recent one too?), with and given don't always topicalize.

$_ = 33;
with 42 -> $ { .say }  # 33
given 42 -> $ { .say } # 33

Their name was chosen to reflect this difference:

  • The English words "with" and "given" as the first word in a clause fairly strongly imply they're establishing a topic. (In Raku this implication can be naturally overridden by following the value with -> .... where the ... is not $_.)

  • Conversely, "if" only very weakly suggests it's establishing a topic, and in programming languages not at all afaik. (In Raku this suggestion can be hoisted to reading naturally strongly by following the value with -> $_ or some other signature with $_ in it.)

raiph avatar Mar 17 '23 21:03 raiph

With, hmm, given, er, using a 2022 Rakudo (and, I'm guessing, a recent one too?), with and given don't always topicalize.

Very good point. My statement was reduced to focus on consistency, but in the context of documentation this is really important.

vrurg avatar Mar 18 '23 01:03 vrurg