Open
Description
Elm 0.19.1
elm.js:2166 Uncaught RangeError: Maximum call stack size exceeded
at _Platform_gatherEffects (elm.js:2166)
at _Platform_gatherEffects (elm.js:2179)
...
This function is not tail recursive when working with a nested Cmd.batch
. Large flat batches are ok, since a for loop is used to iterate those.
https://github.com/elm/core/blob/master/src/Elm/Kernel/Platform.js#L273
Workarounds:
- Don't create large nested Cmd.batch.
- OR Users can write their own custom version of
Cmd.batch
that keeps the batch flat, and gets transformed into aCmd.batch
later one, once the whole batch has been built.
===
It is conventient to use an update monad like this:
andThen :
(model -> ( model, Cmd msg ))
-> ( model, Cmd msg )
-> ( model, Cmd msg )
andThen fn ( model, cmd ) =
let
( nextModel, nextCmd ) =
fn model
in
( nextModel, Cmd.batch [ cmd, nextCmd ] )
When operating over a large number of update functions, which are written in this style:
someUpdate : ... -> Model -> ( Model, Cmd Msg )
It can be convenient to create a larger update by folding over a list of smaller ones, like this:
List.foldl
(\... accum ->
andThen
(someUpdate ...)
accum
)
( model, Cmd.none )
Even if the smaller someUpdate
functions return Cmd.none
, a large nested Cmd.batch
will be created.
This can be fixed by avoiding using this style of programming, but it seems a shame to not allow it.
Solutions:
- Make _Platform_gatherEffects tail recursive.
- OR Make
Cmd.batch
a bit smarter, by having it flatten any nested batching.
Metadata
Metadata
Assignees
Labels
No labels