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

Pattern matching with _ forces computation of lazy fields too eagerly #10465

Open
radeusgd opened this issue Jul 6, 2024 · 2 comments
Open
Assignees
Labels
--bug Type: bug -compiler p-lowest Should be completed at some point

Comments

@radeusgd
Copy link
Member

radeusgd commented Jul 6, 2024

Let me show this on example:

from Standard.Base import all

type My_Ref
    Lazy ~lazy
    Eager eager

    get_if_eager self = case self of
        My_Ref.Eager x -> x
        My_Ref.Lazy _ -> Nothing

    get self should_compute:Boolean = case self of
        My_Ref.Eager x -> x
        My_Ref.Lazy x -> if should_compute then x else Nothing

    tricky_get_if_eager self =
        atom = Meta.meta self
        if atom.constructor.name == "Eager" then atom.value else Nothing

main =
    v1 = My_Ref.Lazy <|
        IO.println "Computing v1"
        42
    
    IO.println (v1.get_if_eager)

    v2 = My_Ref.Lazy <|
        IO.println "Computing v2"
        44

    IO.println (v2.get False)

    v3 = My_Ref.Lazy <|
        IO.println "Computing v3"
        46

    IO.println (v3.tricky_get_if_eager)

The current behaviour is as follows:

Computing v1
Nothing
Computing v2
Nothing
Nothing

As we can see both v1 and v2 are computed. I think this is wrong.

Ideally, neither of them should be computed as we don't use either value.

It seems acceptable to compute v2 as we are binding the value to x so it seems OK to force it to compute. However ideally, the variable x could 'inherit' the laziness and only be computed if it is actually demanded (as if it were an ~suspended argument). It could possibly be marked by using My_Ref.Lazy ~x -> ... in the pattern match. Currently I have checked and adding the ~ to x and _ does not change the behaviour.

However, for _ it should really be noted to not be computed as we explicitly ignore the value. This makes decomposing a value without triggering execution quite hard - as shown in tricky_get_if_eager - the only variant that currently works as desired.

@radeusgd
Copy link
Member Author

radeusgd commented Jul 6, 2024

I've encountered this issue when debugging why Snowflake batching does not improve performance.

Apparently, our SQL_Type_Reference.to_type_override function that was supposed to avoid triggering the lazy computation, was actually triggering it due to this problem.

radeusgd added a commit that referenced this issue Jul 6, 2024
@radeusgd radeusgd added the p-lowest Should be completed at some point label Jul 8, 2024
@radeusgd
Copy link
Member Author

radeusgd commented Jul 8, 2024

Marking as lowest priority since an easy workaround exists - as demonstrated by tricky_get_if_eager.

The workaround is slightly annoying, but usable.

@JaroslavTulach JaroslavTulach changed the title Pattern matching forces computation of lazy fields too eagerly Jul 9, 2024
@JaroslavTulach JaroslavTulach self-assigned this Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
--bug Type: bug -compiler p-lowest Should be completed at some point
2 participants