elm / virtual-dom

The foundation of HTML and SVG in Elm.
https://package.elm-lang.org/packages/elm/virtual-dom/latest
BSD 3-Clause "New" or "Revised" License
209 stars 80 forks source link

Html equality... lazy-evaluation problem !? #113

Closed yormi closed 7 years ago

yormi commented 7 years ago

Hi fellows,

I'm trying to solve this problem and I'm wondering if you can help me: https://github.com/eeue56/elm-html-test/issues/37

I think it is related to this issue as well: https://github.com/elm-lang/virtual-dom/issues/13

Here's the test that I need to make pass with elm 0.18. Right now, it throws:

This test failed because it threw an exception: "Error: Trying to use (==) on functions. There is no way to know if functions are "the same" in the Elm sense. Read more about this at http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#== which describes why it is this way and what the better version will look like."

test "works with functions rendering (onInput f) where f is a function" <|
    \() ->
        let
            html1 =
                someHtml "a"

            html2 =
                 someHtml "b"

            someHtml unused =
                div []
                    [ h1
                        [ E.onInput (\s -> A s) ]
                        []
                    ]
        in
            (html1 == html2)
                |> Expect.true ""

type Msg
    = A String

Points to note:

  1. If I replace (\s -> A s) by A it works
  2. If I remove the unused parameter to someHtml, no problems.
  3. If I use the lazy way (Html.lazy someHtml "a") then there's no error but the test still fails.

Questions

  1. So how can I compare those 2 !?
  2. When diffing the html after model changes, how would these be compared ?
  3. Where can I find the code that does this ?

Any help would be appreciated :)

process-bot commented 7 years ago

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.

zwilias commented 7 years ago

Equality in Elm on functions only "works" when dealing with referential equality.

Because of eager evaluation, you end up with the same event handler in the case where your html-producing takes no arguments. Similarly, if the event mapping function is simply A, it's referentially equal to another A. By having a parameter on your html-producing function - even if you actually ignore it - evaluation doesn't happen until all arguments are passed, so you'll end up with two separate (\s -> A s) functions that are not referentially equal.

Note that this is not a virtual-dom issue and expected behaviour.

Let's continue trying to find a way for your use-case to be supported through the issue you logged on elm-html-test.

yormi commented 7 years ago

Thanks a lot for the explanation. That's what I thought was happening but with your explanation I feel I understand better :)

Closing here and continuing here