enso-org / enso

Enso Analytics is a self-service data prep and analysis platform designed for data teams.
https://ensoanalytics.com
Apache License 2.0
7.37k stars 323 forks source link

Type pattern match for builtin types matches also the type itself #5309

Closed wdanilo closed 1 year ago

wdanilo commented 1 year ago

This task is automatically imported from the old Task Issue Board and it was originally created by Radosław Waśko. Original issue is here.


When writing

f e = case e of
    _ : Date -> True
    _ -> False

I expect such a branch to match any instance of a Date but not the Date type itself.

i.e. i'd expect

f (Date.new 1999 12 12) == True
f Date == False

however with the current implementation - both would be true! This is inconsistent with custom defined Enso atoms where it will behave as expected for

type Foo
    Bar x

I will get

g e = case e of
    _ : Foo -> True
    _ -> False
g (Foo.Bar 42) == True
g Foo == False

as expected.

I have checked that this is the case for at least Date and Integer types, likely for more.

Here's a more complete repro:

from Standard.Base import all

domatch v =
    a = case v of
        Date -> "Date type"
        _ : Date -> "Date value"
        _ -> "other"
    b = case v of
        _ : Date -> "Date value"
        Date -> "Date type"
        _ -> "other"
    IO.println v.to_text+" -> "+[a, b].to_text

domatch2 v =
    a = case v of
        Integer -> "Integer type"
        _ : Integer -> "Integer value"
        _ -> "other"
    b = case v of
        _ : Integer -> "Integer value"
        Integer -> "Integer type"
        _ -> "other"
    IO.println v.to_text+" -> "+[a, b].to_text

type Foo
    Bar x

domatch3 v =
    a = case v of
        Foo -> "Foo type"
        _ : Foo -> "Foo value"
        _ -> "other"
    b = case v of
        _ : Foo -> "Foo value"
        Foo -> "Foo type"
        _ -> "other"
    IO.println v.to_text+" -> "+[a, b].to_text

main =
    IO.println "Matching date:"
    domatch Date
    domatch (Date.new 2022 10 12)
    domatch 42
    IO.println "Matching integer:"
    domatch2 42
    domatch2 Integer
    domatch2 (Date.new 2022 10 12)
    IO.println "Matching custom type (Foo):"
    domatch3 Foo
    domatch3 (Foo.Bar 42)
    domatch3 42

I'm getting:

Matching date:
Date -> ['Date type', 'Date value']
2022-10-12 -> ['Date value', 'Date value']
42 -> ['other', 'other']
Matching integer:
42 -> ['Integer value', 'Integer value']
Integer -> ['Integer type', 'Integer value']
2022-10-12 -> ['other', 'other']
Matching custom type (Foo):
Foo -> ['Foo type', 'Foo type']
(Bar 42) -> ['Foo value', 'Foo value']
42 -> ['other', 'other']

while I'd expect to always have consistent results regardless of branch ordering here - _ : Date -> and Date -> should be completely distinct branches:

Matching date:
Date -> ['Date type', 'Date type']
2022-10-12 -> ['Date value', 'Date value']
42 -> ['other', 'other']
Matching integer:
42 -> ['Integer value', 'Integer value']
Integer -> ['Integer type', 'Integer type']
2022-10-12 -> ['other', 'other']
Matching custom type (Foo):
Foo -> ['Foo type', 'Foo type']
(Bar 42) -> ['Foo value', 'Foo value']
42 -> ['other', 'other']

Comments:

Discord discussion thread https://discord.com/channels/401396655599124480/1044380778085228564/1044380778085228564 (Radosław Waśko - Nov 21, 2022)


jdunkerley commented 1 year ago

@JaroslavTulach to verify if this is still an issue.

JaroslavTulach commented 1 year ago

Verified in REPL. The problem is fixed, probably by #3949:

enso --repl
> f e = case e of
>     _ : Date -> True
>     _ -> False
>>> Nothing
> f Date
>>> false
> f (Date.new 1999 12 12)
>>> true
enso-bot[bot] commented 1 year ago

Jaroslav Tulach reports a new STANDUP for yesterday (2023-02-07):

Progress: - Turned performance work into GitHub issues.

Next Day: Move to regex.