Stream: beginners

Topic: Spooky tag behaviour in if/else


view this post on Zulip David Dunn (Feb 01 2023 at 04:54):

Ran into some strange behaviour when adding an if branch that returns a tag instead of a string:

app "spookyTags"
    packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.2.0/8tCohJeXMBUnjo_zdMq0jSaqdYoCWJkWazBd4wa8cQU.tar.br" }
    imports [pf.Stdout]
    provides [main] to pf

main =
    Stdout.line "ifThenString: \(ifThenString)\ncaseStr: \(caseStr)"

count = 5

ifThenString =
    if count > 0 then
        "red"
    else if count == 0 then
        "yellow"
    else if count % 2 == 0 then
        "purple"
    else
        "green"

ifThenCase =
    if count > 0 then
        Red
    else if count == 0 then
        Yellow
    #else if count % 2 == 0 then
    #    Purple
    else if count < 0 then
        Zulip
    else
        Green

caseStr =
    when ifThenCase is
        Red -> "red"
        Green -> "green"
        Yellow -> "yellow"
        Zulip -> "zulip"

This gives the expected red/red output, but uncommenting the purple branch doesn't produce an error in caseStr as expected. Instead it outputs red/yellow, which leads me to believe that adding the purple branch is changing the evaluation of the previous if expressions.

Further, swapping branches in the if, the when or both has no effect on the value of caseStr: it's always "yellow" when the purple if branch is present. Even moving red around doesn't change anything, and I added the "Zulip" tag just in case it was taking the last tag alphabetically.

The only thing I've found that gives red/red output with the purple branch uncommented is adding a corresponding purple branch to caseStr.

I couldn't spot an existing thread or issue for this, so wanted to check if I'm missing something before opening an issue.

view this post on Zulip Brendan Hansknecht (Feb 01 2023 at 07:03):

So, @Ayaz Hafiz can confirm, but I think this is a bug with defaulting to open tags ( a newer change to the language). The code you posted above should fail to type check. In fact, if you give ifThenCase a type with ifThenCase : [Red, Yellow, Purple, Zulip, Green], it will fail to type check.

Anyway, what is happening. ifThenCase is a tag of Red, Yellow, Purple, Zulip, Green. If you sort and number that, you get:
Green -> 0
Purple -> 1
Red -> 2
Yellow -> 3
Zulip -> 4

The when in caseStr is matching assuming a tag of Red, Yellow, Zulip, Green. If you sort and number that, you get:
Green -> 0
Red -> 1
Yellow -> 2
Zulip -> 3

If you match up the numbers. The first tag returns Red which is a value of 2. The second tag sees 2 which it thinks is Yellow. So you get the final output of "yellow".

view this post on Zulip Brendan Hansknecht (Feb 01 2023 at 07:03):

So yeah, a compiler type checking bug if I am accurate.

view this post on Zulip David Dunn (Feb 01 2023 at 07:39):

Perfect! Thanks for the explanation. Should I open an issue for it?

view this post on Zulip Brendan Hansknecht (Feb 01 2023 at 07:51):

Yes please

view this post on Zulip David Dunn (Feb 01 2023 at 19:19):

Gotcha: https://github.com/roc-lang/roc/issues/4994

view this post on Zulip Ayaz Hafiz (Feb 02 2023 at 04:04):

https://github.com/roc-lang/roc/pull/4996 should fix this


Last updated: Jul 06 2025 at 12:14 UTC