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

Undefined variable being passed to a function does not raise compiler error #1063

Closed
fiatjaf opened this issue Sep 18, 2015 · 5 comments
Closed

Comments

@fiatjaf
Copy link

fiatjaf commented Sep 18, 2015

Deep down in the "cases" of my update function, there is this:

update : Action -> Model -> (Model, Effects Action)
update action model =
  case action of
    (other cases)
    BoardAction boardAction ->
      let
        (board, effects) = Board.update boardAction board
      in
        (
          { model |
            board <- board
          }
        , Effects.map (BoardAction) effects
        )

Where I passed that last board argument I should have passed model.board, but I made this mistake, and the compiler did not complain. Now I tried replacing board for other arbitrary names, but then the compiler noted the mistake and compilation failed.

Then I tried the following:

    BoardAction boardAction ->
      let
        (hahaha, effects) = Board.update boardAction hahaha
      in
        (
          { model |
            board <- hahaha
          }
        , Effects.map (BoardAction) effects
        )

and the compiler allowed.

Running the program compiled this way I get a runtime error somewhere where I needed a property of model.board:

Uncaught TypeError: Cannot read property 'columns' of undefined

'columns' is a property of model.board, but here's where I think the problem could be better inspected, in the generated code for BoardAction:

   var update = F2(function (action,
   model) {
      return function () {
         switch (action.ctor)
         {case "BoardAction":
            return function () {
                 var $ = A2($Board.update,
                 action._0,
                 hahaha),
                 hahaha = $._0,
                 effects = $._1;
                 return {ctor: "_Tuple2"
                        ,_0: _U.replace([["board"
                                         ,hahaha]],
                        model)
                        ,_1: A2($Effects.map,
                        BoardAction,
                        effects)};
              }();

or, in the printscreen version with all the important values:

@rgrempel
Copy link

But isn't the problem that hahaha is defined -- it's just defined recursively in a way that doesn't actually work?

What I mean is that the compiler would detect a completely undefined variable -- what it's not detecting here is something different, that is, a recursive definition that doesn't make sense.

@evancz
Copy link
Member

evancz commented Sep 19, 2015

I have only read the title of this issue, but there's a very high chance this is a duplicate of #873. Can you take a look at all the issues that reference it and see if this looks the same?

@fiatjaf
Copy link
Author

fiatjaf commented Sep 19, 2015

It looks the same.

@evancz
Copy link
Member

evancz commented Sep 19, 2015

Okay, cool! The plan is to have this fixed in 0.16. We know where the code should go and how it should work, just need to write it down :) So look out for the fix in the next release. If you want to follow along, I may do an update on #873 when it is fixed in the master branch of the compiler.

Thanks for the report, and sorry you ran into this! 0.16 also has stuff like "recognize when a case does not handle all possible inputs", so the implementation of Elm is well on the way to really having no silly runtime errors.

@evancz evancz closed this as completed Sep 19, 2015
@evancz
Copy link
Member

evancz commented Sep 19, 2015

And @rgrempel's explanation is a good way to think of this. Elm allows self-recursive values, which is often nice. Like for functions. We did not know exactly how to restrict it to disallow just the bad cases (like the one you ran into) until relatively recently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants