elm / compiler

Compiler for Elm, a functional language for reliable webapps.
https://elm-lang.org/
BSD 3-Clause "New" or "Revised" License
7.56k stars 661 forks source link

lock on d.dat somehow outlives `elm repl` session #2139

Open landongrindheim opened 4 years ago

landongrindheim commented 4 years ago

Quick Summary: While trying out the Elm REPL I found myself in a situation where I crashed the REPL and can no longer start a new session and do anything in it without it crashing as soon as I type anything and hit <enter>. I've included the session that lead to the crash, as well as some subsequent crashes. Please let me know if there's anything else that I could provide which would be helpful 🙂

REPL sessions (including shell history) ```bash lgrindheim ~ $ elm repl ---- Elm 0.19.1 ---------------------------------------------------------------- Say :help for help and :exit to exit! More at -------------------------------------------------------------------------------- > "Ahoy, World!" "Ahoy, World!" : String > "Ahoy " ++ "World!" "Ahoy World!" : String > type "Ahoy" | > "Pi is " ++ String.fromFloat pi ++ "(give or take)" "Pi is 3.141592653589793(give or take)" : String > "Pi is " ++ String.fromFloat(pi) ++ "(give or take)" "Pi is 3.141592653589793(give or take)" : String > 1 + 1 2 : number > 23.0 + 1 24 : Float > 23.0 + 1.9 24.9 : Float > 12345 - (9 + 1) 12335 : number > 12345 - 9 + 1 12337 : number > 9 // 3 3 : Int > 9 / 2 4.5 : Float > 9 // 2 4 : Int > 'a' 'a' : Char > 'abc' | -- NEEDS DOUBLE QUOTES ---------------------------------------------------- REPL The following string uses single quotes: 3| 'abc' ^^^^^ Please switch to double quotes instead: 'this' => "this" Note: Elm uses double quotes for strings like "hello", whereas it uses single quotes for individual characters like 'a' and 'ø'. This distinction helps with code like (String.any (\c -> c == 'X') "90210") where you are inspecting individual characters. > // this | -- MISSING EXPRESSION ----------------------------------------------------- REPL I am partway through parsing the `repl_input_value_` definition, but I got stuck here: 2| repl_input_value_ = 3| // this ^ I was expecting to see an expression like 42 or "hello". Once there is something there, I can probably give a more specific hint! Note: This can also happen if run into reserved words like `let` or `as` unexpectedly. Or if I run into operators in unexpected spots. Point is, there are a couple ways I can get confused and give sort of weird advice! > some_Rad__THING__ -- NAMING ERROR ----------------------------------------------------------- REPL I cannot find a `some_Rad__THING__` variable: 3| some_Rad__THING__ ^^^^^^^^^^^^^^^^^ These names seem close though: String.toInt Debug.toString List.range Maybe.andThen Hint: Read to see how `import` declarations work in Elm. > some_Rad__THING__ = 1 1 : number > some_Rad__THING__ 1 : number > pi 3.141592653589793 : Float > f = pi 3.141592653589793 : Float > f 3.141592653589793 : Float > not False True : Bool > not True False : Bool > not 1 -- TYPE MISMATCH ---------------------------------------------------------- REPL The 1st argument to `not` is not what I expect: 5| not 1 ^ This argument is a number of type: number But `not` needs the 1st argument to be: Bool Hint: Only Int and Float values work as numbers. > not 2 -- TYPE MISMATCH ---------------------------------------------------------- REPL The 1st argument to `not` is not what I expect: 5| not 2 ^ This argument is a number of type: number But `not` needs the 1st argument to be: Bool Hint: Only Int and Float values work as numbers. > not "this" -- TYPE MISMATCH ---------------------------------------------------------- REPL The 1st argument to `not` is not what I expect: 5| not "this" ^^^^^^ This argument is a string of type: String But `not` needs the 1st argument to be: Bool Hint: Elm does not have “truthiness” such that ints and strings and lists are automatically converted to booleans. Do that conversion explicitly! > not true -- NAMING ERROR ----------------------------------------------------------- REPL I cannot find a `true` variable: 5| not true ^^^^ These names seem close though: e tan turns abs Hint: Read to see how `import` declarations work in Elm. > true = False False : Bool > true False : Bool > 1 == 2 False : Bool > 1 /= 2 True : Bool > 1 /= 2 == True -- INFIX PROBLEM ---------------------------------------------------------- REPL You cannot mix (/=) and (==) without parentheses. 6| 1 /= 2 == True ^^^^^^^^^^^^^^ I do not know how to group these expressions. Add parentheses for me! > (1 /= 2) == True True : Bool > (1 /= 2) /= True False : Bool > let dash = '-' | -- UNFINISHED LET --------------------------------------------------------- REPL I was partway through parsing a `let` expression, but I got stuck here: 6| let dash = '-' ^ I was expecting to see the in keyword next. Or maybe more of that expression? Note: Here is an example with a valid `let` expression for reference: viewPerson person = let fullName = person.firstName ++ " " ++ person.lastName in div [] [ text fullName ] Here we defined a `viewPerson` function that turns a person into some HTML. We use a `let` expression to define the `fullName` we want to show. Notice the indentation! The `fullName` is indented more than the `let` keyword, and the actual value of `fullName` is indented a bit more than that. That is important! > dash = '-' '-' : Char > isKeepable character = character /= dash : Char -> Bool > withoutDashes str = String.filter isKeepable str : String -> String > withoutDashes "abd" "abd" : String > withoutDashes "abd-" "abd" : String > withoutDashes "abd-----cccc-c-c-c-c-c--c-c-c-c-c" "abdcccccccccccccc" : String > withoutDashes str = | let | dash = '-' | isKeepable char = char /= dash | -- UNFINISHED LET --------------------------------------------------------- REPL I was partway through parsing a `let` expression, but I got stuck here: 3| let 4| dash = '-' 5| isKeepable char = char /= dash ^ I was expecting to see the in keyword next. Or maybe more of that expression? Note: Here is an example with a valid `let` expression for reference: viewPerson person = let fullName = person.firstName ++ " " ++ person.lastName in div [] [ text fullName ] Here we defined a `viewPerson` function that turns a person into some HTML. We use a `let` expression to define the `fullName` we want to show. Notice the indentation! The `fullName` is indented more than the `let` keyword, and the actual value of `fullName` is indented a bit more than that. That is important! > withoutDashes str = | let | dash = '-' | isKeepable char = char /= dash | in | String.filter isKeepable str | -- SHADOWING -------------------------------------------------------------- REPL The name `dash` is first defined here: 2| dash = '-' ^^^^ But then it is defined AGAIN over here: 9| dash = '-' ^^^^ Think of a more helpful name for one of them and you should be all set! Note: Linters advise against shadowing, so Elm makes “best practices” the default. Read for more details on this choice. -- SHADOWING -------------------------------------------------------------- REPL The name `isKeepable` is first defined here: 4| isKeepable character = character /= dash ^^^^^^^^^^ But then it is defined AGAIN over here: 10| isKeepable char = char /= dash ^^^^^^^^^^ Think of a more helpful name for one of them and you should be all set! Note: Linters advise against shadowing, so Elm makes “best practices” the default. Read for more details on this choice. > lgrindheim ~ $ elm repl ---- Elm 0.19.1 ---------------------------------------------------------------- Say :help for help and :exit to exit! More at -------------------------------------------------------------------------------- > withoutDashes str = | let | dash = '-' | isKeepable char = char /= dash | in | String.filter isKeepable str | elm: /Users/lgrindheim/.elm/0.19.1/repl/tmp/elm-stuff/0.19.1/d.dat: openBinaryFile: resource busy (file is locked) lgrindheim ~ $ elm repl ---- Elm 0.19.1 ---------------------------------------------------------------- Say :help for help and :exit to exit! More at -------------------------------------------------------------------------------- > withoutDashes str = | let | dash = '-' | isKeepable char = char /= dash | in | String.filter isKeepable str | : String -> String > withoutDashes "888-888-8888" "8888888888" : String > \w h = w * h | -- UNFINISHED ANONYMOUS FUNCTION ------------------------------------------ REPL I just saw the beginning of an anonymous function, so I was expecting to see an arrow next: 10| \w h = w * h ^ The syntax for anonymous functions is (\x -> x + 1) so I am missing the arrow and the body of the function. > \w h -> w * h : number -> number -> number > area = \w h -> w * h : number -> number -> number > area 5 4 20 : number > String.filter (\char -> char /= '-') "555-555-5555" "5555555555" : String > String.filter \char -> char /= '-' "555-555-5555" | -- SYNTAX PROBLEM --------------------------------------------------------- REPL I got stuck here: 11| String.filter \char -> char /= '-' "555-555-5555" ^ Whatever I am running into is confusing me a lot! Normally I can give fairly specific hints, but something is really tripping me up this time. > (/) : Float -> Float -> Float > (/) 15 3 5 : Float > (== (+ 5 3) (- 9 1)) | -- UNFINISHED OPERATOR FUNCTION ------------------------------------------- REPL I was expecting a closing parenthesis here: 11| (== (+ 5 3) (- 9 1)) ^ Try adding a ) to see if that helps! Note: I think I am parsing an operator function right now, so I am expecting to see something like (+) or (&&) where an operator is surrounded by parentheses with no extra spaces. > (== ((+) 5 3) ((-) 9 1)) | -- UNFINISHED OPERATOR FUNCTION ------------------------------------------- REPL I was expecting a closing parenthesis here: 11| (== ((+) 5 3) ((-) 9 1)) ^ Try adding a ) to see if that helps! Note: I think I am parsing an operator function right now, so I am expecting to see something like (+) or (&&) where an operator is surrounded by parentheses with no extra spaces. > (==) ((+) 5 3) ((-) 9 1)) | -- UNEXPECTED PARENTHESIS ------------------------------------------------- REPL I ran into an unexpected parenthesis: 11| (==) ((+) 5 3) ((-) 9 1)) ^ This ) does not match up with an earlier open parenthesis. Try deleting it? > (==) ((+) 5 3) ((-) 9 1) True : Bool > negate =1 1 : number > negate 1 -- TOO MANY ARGS ---------------------------------------------------------- REPL The `negate` value is not a function, but it was given 1 argument. 12| negate 1 ^^^^^^ Are there any missing commas? Or missing parentheses? > pi 3.141592653589793 : Float > pi = 2 2 : number > lgrindheim ~ $ elm repl ---- Elm 0.19.1 ---------------------------------------------------------------- Say :help for help and :exit to exit! More at -------------------------------------------------------------------------------- > negate 1 elm: /Users/lgrindheim/.elm/0.19.1/repl/tmp/elm-stuff/0.19.1/d.dat: openBinaryFile: resource busy (file is locked) lgrindheim ~ $ elm repl ---- Elm 0.19.1 ---------------------------------------------------------------- Say :help for help and :exit to exit! More at -------------------------------------------------------------------------------- > negate 1 elm: /Users/lgrindheim/.elm/0.19.1/repl/tmp/elm-stuff/0.19.1/d.dat: openBinaryFile: resource busy (file is locked) lgrindheim ~ $ vi /Users/lgrindheim/.elm/0.19.1/repl/tmp/elm-stuff/0.19.1/d.dat lgrindheim ~ $ elm repl ---- Elm 0.19.1 ---------------------------------------------------------------- Say :help for help and :exit to exit! More at -------------------------------------------------------------------------------- > negate 1 elm: /Users/lgrindheim/.elm/0.19.1/repl/tmp/elm-stuff/0.19.1/d.dat: openBinaryFile: resource busy (file is locked) lgrindheim ~ $ elm repl ---- Elm 0.19.1 ---------------------------------------------------------------- Say :help for help and :exit to exit! More at -------------------------------------------------------------------------------- > abc elm: /Users/lgrindheim/.elm/0.19.1/repl/tmp/elm-stuff/0.19.1/d.dat: openBinaryFile: resource busy (file is locked) lgrindheim ~ $ elm repl ---- Elm 0.19.1 ---------------------------------------------------------------- Say :help for help and :exit to exit! More at -------------------------------------------------------------------------------- > a = 1 elm: /Users/lgrindheim/.elm/0.19.1/repl/tmp/elm-stuff/0.19.1/d.dat: openBinaryFile: resource busy (file is locked) ^C > lgrindheim ~ $ elm repl ---- Elm 0.19.1 ---------------------------------------------------------------- Say :help for help and :exit to exit! More at -------------------------------------------------------------------------------- > String.toUpper "abc" elm: /Users/lgrindheim/.elm/0.19.1/repl/tmp/elm-stuff/0.19.1/d.dat: openBinaryFile: resource busy (file is locked) lgrindheim ~ $ elm repl ---- Elm 0.19.1 ---------------------------------------------------------------- Say :help for help and :exit to exit! More at -------------------------------------------------------------------------------- > String.toUpper "abc" elm: /Users/lgrindheim/.elm/0.19.1/repl/tmp/elm-stuff/0.19.1/d.dat: openBinaryFile: resource busy (file is locked) ```

Additional Details

github-actions[bot] commented 4 years ago

Thanks for reporting this! To set expectations:

Finally, please be patient with the core team. They are trying their best with limited resources.

landongrindheim commented 4 years ago

I'm not sure what caused elm-repl to un-freeze, but it seemed to recover after issuing <enter> a number of times without input.

After I finally had a valid session again, I was able to reproduce this issue the following:

 ~ $ elm repl
---- Elm 0.19.1 ----------------------------------------------------------------
Say :help for help and :exit to exit! More at <https://elm-lang.org/0.19.1/repl>
--------------------------------------------------------------------------------
> var = 1
1 : number
> dash = '-'
'-' : Char
> isKeepable chr = chr /= dash
<function> : Char -> Bool
> withoutDashes str = String.filter isKeepable str
<function> : String -> String
> anotherWithoutDashes str =
|   let
|     dash = '-'
|     isKeepable chr = chr /= dash
|   in
|   String.filter isKeepable str
|
-- SHADOWING -------------------------------------------------------------- REPL

The name `dash` is first defined here:

9| dash = '-'
   ^^^^
But then it is defined AGAIN over here:

4|     dash = '-'
       ^^^^
Think of a more helpful name for one of them and you should be all set!

Note: Linters advise against shadowing, so Elm makes “best practices” the
default. Read <https://elm-lang.org/0.19.1/shadowing> for more details on this
choice.

-- SHADOWING -------------------------------------------------------------- REPL

The name `isKeepable` is first defined here:

10| isKeepable chr = chr /= dash
    ^^^^^^^^^^
But then it is defined AGAIN over here:

5|     isKeepable chr = chr /= dash
       ^^^^^^^^^^
Think of a more helpful name for one of them and you should be all set!

Note: Linters advise against shadowing, so Elm makes “best practices” the
default. Read <https://elm-lang.org/0.19.1/shadowing> for more details on this
choice.

I then left elm-repl and started it:

 ~ $ elm repl
---- Elm 0.19.1 ----------------------------------------------------------------
Say :help for help and :exit to exit! More at <https://elm-lang.org/0.19.1/repl>
--------------------------------------------------------------------------------
> abc = 1
elm: /Users/lgrindheim/.elm/0.19.1/repl/tmp/elm-stuff/0.19.1/d.dat: openBinaryFile: resource busy (file is locked)