Slowly climbing up the Elm learning curve, I made it crash runtime 
yesterday, and I just wanted to report to the mailing list.  This may be a 
known issue, but as a novice I'm making all kinds of rookie mistakes.  As 
such, when those rookie mistakes cause a runtime crash without a compiler 
complaint, I'll try to report them here.

The short version:  You can do this in Elm:

> v = v+1
NaN : number

I would have expected that to crash, because v is being used before it is 
defined.

In the clojurescript repl, I get a similar case:

cljs.user=> v
WARNING: Use of undeclared Var cljs.user/v at line 1 <cljs repl>
nil
cljs.user=> (def v (+ v 1))
#'cljs.user/v
cljs.user=> v
NaN

But in the clojure repl (Java based, not JavaScript), I get the crash I was 
looking for.

boot.user=> (def v (+ v 1))

clojure.lang.Compiler$CompilerException: java.lang.ClassCastException: 
clojure.lang.Var$Unbound cannot be cast to java.lang.Number, 
compiling:(boot.user7277212806697690427.clj:1:8)
           java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be 
cast to java.lang.Number


I suspect this will always be the case, but it led to a runtime crash, as 
explain in the longish writeup below


Background, I want a date picker element in my page, so I copied in the 
elm-datepicker ( https://github.com/Bogdanp/elm-datepicker).  In copying I 
omitted something I thought was small, which in turn caused my program to 
pass compiling but crash runtime.

The code snippet from the real example that broke relates to the "update" 
behavior.  The original says:

```
update : Msg -> Model -> ( Model, Cmd Msg )
update msg ({ datePicker } as model) =
    case msg of
        ToDatePicker msg ->
            let
                ( datePicker, datePickerFx, mDate ) =
                    DatePicker.update msg datePicker
    ...
```

Note the construct `({datePicker} as model)`  As a newcomer, that is 
something I've never seen before.  Not something that is documented on the 
"syntax" page (http://elm-lang.org/docs/syntax), and not something I can 
find in the get started guide.  
https://guide.elm-lang.org/get_started.html  I *guessed* that it was some 
sort of way to desctructure the incoming model argument, but because I had 
many cases, I didn't want to bother with that for just this one case.

(Better docs would probably have helped my understanding, but this is  
young language...if I just wanted better docs, I'd still be using 
JavaScript)

Anyway, I dropped the destructuring thing, whatever it is.  My version 
looked like:

```
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    ToDatePicker rec ->
            let
                ( datePicker, datePickerFx, mDate ) =
                    DatePicker.update rec datePicker     -- <== bug here!
   ...
```

I changed the incoming destructuring thing, and I swapped out the nested 
redefinition of "msg" for "rec", but I *forgot* to say "model.datePicker" 
inside the let statement.

Strangely, this compiles just fine.  I would have expected to see at least 
a warning, because the rhs of the assignment is using a variable that is 
first declared on the lhs of the assignment.  Actually, no.  That's too 
weak.  I expect the compiler to bomb out in such a case.

But it doesn't

```
=================================== WARNINGS 
===================================

-- unused import - 
/home/james/repos/jem/calvad/calvad_ui/elm-calvadui/src/elm/Main.elm

Module `Date.Extra.Format` is unused.

15| import Date.Extra.Format as Format exposing (format, 
isoDateFormat,formatUtc, isoStringNoOffset)
    
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Best to remove it. Don't save code quality for later!

Success! Compiled 1 module.
Successfully generated /tmp/116830-14831-1hiiwmv.2po3kdquxr.js
```

(The warning that *is* there relates to an unused module, not to the usage 
of an undeclared variable.)

Running that, I see the following runtime crash:

```
TypeError: _p23 is undefined
_Bogdanp$elm_datepicker$DatePicker$update<() c4836e16ec49f9b909df.js:35001
A2()                                                                           
c4836e16ec49f9b909df.js:25776
_jmarca$elm_calvadui$Main$update<()                  
c4836e16ec49f9b909df.js:37131
... blah blah blah ...
```

Of course it crashes, because datePicker is undefined when 
DatePicker.update is called on it.  Once I spotted the error the fix was 
easy, but it took probably 2 hours for me to spot it.

My guess is that using undefined variables that get 
auto-defined-and-hoisted will always be a problem because this is 
JavaScript under the hood. This also affects clojurescript apparently, as 
is shown by my tl;dr up above.  Only clojure/java crash properly when using 
undefined variables.


Regards,
James

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to