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

Method dispatch ordering: should we traverse all multi values before checking the parent types? #12185

Open
radeusgd opened this issue Jan 29, 2025 · 2 comments
Assignees
Labels

Comments

@radeusgd
Copy link
Member

Yet another issue encountered when working on #12165.

See this script:

from Standard.Base import all

type My_Atom
    Value a

    method_1 self = "My_Atom.method_1"

type My_Refinement
    Value x

    method_1 self = "My_Refinement.method_1"
    is_nothing self = "My_Refinement.is_nothing"

My_Refinement.from (that : My_Atom) -> My_Refinement =
    My_Refinement.Value that

prepare_atom =
    (My_Atom.Value 42) : My_Atom & My_Refinement

main =
    x = prepare_atom

    # This will call `method_1` on `My_Atom`, not on `My_Refinement`
    IO.println (x.method_1)

    # If I switch the order, then indeed `method_1` is called on `My_Refinement`
    IO.println ((x : My_Refinement & My_Atom).method_1)

    # This is currently calling `is_nothing` on `My_Refinement`, but shouldn't it call the base `is_nothing` coming from `Any`?
    IO.println (x.is_nothing)

    # What if I hide the refinement?
    IO.println ((x : My_Atom|Nothing).is_nothing)

Currently this yields:

My_Atom.method_1
My_Refinement.method_1
My_Refinement.is_nothing
False

As mentioned in the comments - currently if My_Atom does not define is_nothing, we first consider its intersection type and resolve to My_Refinement.is_nothing.

I suggest that this is wrong. My_Atom does have is_nothing defined. It is just not defined directly on it, but 'inherited' from Any. This 'inherited' definition is still directly available on My_Atom, so it should take precedence over the secondary refinement type.

@radeusgd
Copy link
Member Author

The practical aspect of it is - I was trying to call is_nothing on a Table which is a safe operation.

But since #12165, a Table may also sometimes be a Column. When it is both, the is_nothing was now forwarded into Column.is_nothing and returning a new Column... I guess a side problem is that Column.is_nothing returning a Column is also not ideal...

But I think that does not make the dispatch problem smaller. If I have a method on the base type, it should be considered first before trying the 'secondary' values. Or are there any reasons why this shouldn't happen?

@radeusgd radeusgd added the --bug Type: bug label Feb 3, 2025
@JaroslavTulach JaroslavTulach self-assigned this Feb 4, 2025
@JaroslavTulach JaroslavTulach moved this from ❓New to 📤 Backlog in Issues Board Feb 4, 2025
@JaroslavTulach
Copy link
Member

JaroslavTulach commented Feb 5, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: 📤 Backlog
Development

No branches or pull requests

2 participants