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.