Compiler: shadowed variable can lead to runtime error in generated JS

Created on 28 Apr 2016  路  4Comments  路  Source: elm/compiler

Replaces https://github.com/elm-lang/elm-compiler/issues/1223, has SSCCE.

This program:

import Html

bad param =
  identity <| case param of
    Just _ ->
      0

    Nothing ->
      let
        param = True
      in
        if param then 1 else 2

main = Html.text (toString (bad Nothing))

leads to a runtime error.

The 0.17 produced JS is:

var _user$project$Temp1461826735203948$bad = function (param) {
    return _elm_lang$core$Basics$identity(
        function () {
            var _p0 = param;
            if (_p0.ctor === 'Just') {
                return 0;
            } else {
                var param = true;
                return param ? 1 : 2;
            }
        }());
};

Why that is wrong is explained in https://github.com/elm-lang/elm-compiler/issues/1223#issuecomment-169645306.

There is also a test case PR open, as https://github.com/elm-lang/elm-compiler/pull/1253.

bug

Most helpful comment

Variable shadowing like this will be disallowed in 0.19. You can use the same name as things that appear in an exposing, but you will not be able to shadow variables within a local definition.

In other words, this will be resolved by the fact that the initial code will no longer be accepted by the compiler.

All 4 comments

Tracking in #1377

A related code gen bug, though with slightly different characteristics (no "function call around a case expression") was raised as https://github.com/elm-lang/elm-compiler/issues/1428.

Perhaps a slightly simpler example. Outputs "undefined":

import Html

main =
    let x = "outer" in
    (\_ -> 
        let shouldBeOuter = x in
        let x = "inner" in
        Html.text shouldBeOuter
    ) ()
var _user$project$Main$main = _elm_lang$virtual_dom$Native_VirtualDom.staticProgram(
    function () {
        var x = 'outer';
        return function (_p0) {
            var shouldBeOuter = x;
            var x = 'inner';
            return _elm_lang$html$Html$text(shouldBeOuter);
        }(
            {ctor: '_Tuple0'});
    }());

Javascript closure environments = 馃槥

Variable shadowing like this will be disallowed in 0.19. You can use the same name as things that appear in an exposing, but you will not be able to shadow variables within a local definition.

In other words, this will be resolved by the fact that the initial code will no longer be accepted by the compiler.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

willnwhite picture willnwhite  路  4Comments

maxsnew picture maxsnew  路  4Comments

robinheghan picture robinheghan  路  3Comments

ShalokShalom picture ShalokShalom  路  3Comments

zoren picture zoren  路  5Comments