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

Inconsistent compiler behaviour, adding an identity function leading to different outcome #903

Closed
FRosner opened this Issue Aug 27, 2017 · 5 comments

Comments

Projects
None yet
5 participants
@FRosner
Contributor

FRosner commented Aug 27, 2017

Problem

When a locally bound function and a global function have the same name f, then using it as f () or (identity f) () yields different results.

Context

I was trying to implement an ADT representing a circular list. This is what I had so far:

module CircularList exposing (CircularList(..), get, next)


type CircularList a
    = CircularList { val : a, next : () -> CircularList a }


get : CircularList a -> a
get (CircularList { val, next }) =
    val


next : CircularList a -> CircularList a
next (CircularList { val, next }) =
    -- it doesn't work when I just do "next ()"???????
    (Debug.log "next" next) ()

It works as expected and the following test case is green:

test "get" <|
            \() ->
                let
                    s =
                        "bla"

                    a =
                        CircularList { val = s, next = \() -> a }
                in
                    Expect.equal s (CircularList.get (CircularList.next a))

However as soon as I remove the Debug.log and execute next () directly the test never finishes. Looks like the identify call makes the compiler use the locally bound variable, while without, it takes the global function.

See slack discussion for more details.

Environment

  • Elm Version: 0.18.0
  • NPM Version: 5.0.3
  • OS: Mac OS Sierra 10.12.6

Workround

Don't name the local variable the same as the global.

Expected Behaviour

  • The behaviour should be consistent whether I add identity or not
  • The compiler should warn because I am shadowing the global name (or not)
  • If the behaviour cannot be made consistent the code should not compile, forcing you to choose different names
@process-bot

This comment has been minimized.

Show comment
Hide comment
@process-bot

process-bot Aug 27, 2017

Thanks for the issue! Make sure it satisfies this checklist. My human colleagues will appreciate it!

Here is what to expect next, and if anyone wants to comment, keep these things in mind.

process-bot commented Aug 27, 2017

Thanks for the issue! Make sure it satisfies this checklist. My human colleagues will appreciate it!

Here is what to expect next, and if anyone wants to comment, keep these things in mind.

@matekdk

This comment has been minimized.

Show comment
Hide comment
@matekdk

matekdk Aug 27, 2017

It seems that debug statement is getting hold of the argument-next from the argument, while the execution of the method is calling the self-next method instead.

I think that in this case, the compiler should err with a message that there are two different "next" entities in the scope, and it does not know which one to choose.

matekdk commented Aug 27, 2017

It seems that debug statement is getting hold of the argument-next from the argument, while the execution of the method is calling the self-next method instead.

I think that in this case, the compiler should err with a message that there are two different "next" entities in the scope, and it does not know which one to choose.

@zwilias

This comment has been minimized.

Show comment
Hide comment
@zwilias

zwilias Aug 27, 2017

Member

The type-checker and the codegen disagree, leading to an incorrect result. The inner-most next should be the one used, which the type-checker does, but the codegen seems to think this is a recursive function and transforms it to a while loop instead.

@FRosner could you close the issue here and reopen it on elm-lang/elm-compiler instead? Thanks for the report!

Member

zwilias commented Aug 27, 2017

The type-checker and the codegen disagree, leading to an incorrect result. The inner-most next should be the one used, which the type-checker does, but the codegen seems to think this is a recursive function and transforms it to a while loop instead.

@FRosner could you close the issue here and reopen it on elm-lang/elm-compiler instead? Thanks for the report!

@jvoigtlaender

This comment has been minimized.

Show comment
Hide comment
@jvoigtlaender

jvoigtlaender Aug 27, 2017

Contributor

I think this is a known and reported issue.

elm/compiler#1452

Contributor

jvoigtlaender commented Aug 27, 2017

I think this is a known and reported issue.

elm/compiler#1452

@FRosner

This comment has been minimized.

Show comment
Hide comment
@FRosner

FRosner Aug 27, 2017

Contributor

I opened elm/compiler#1636 instead.

Contributor

FRosner commented Aug 27, 2017

I opened elm/compiler#1636 instead.

@FRosner FRosner closed this Aug 27, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment