Skip to content

_Platform_gatherEffects can throw runtime exception - Maximum call stack size exceeded #1123

Open
@rupertlssmith

Description

@rupertlssmith

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:

  1. Don't create large nested Cmd.batch.
  2. OR Users can write their own custom version of Cmd.batch that keeps the batch flat, and gets transformed into a Cmd.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:

  1. Make _Platform_gatherEffects tail recursive.
  2. OR Make Cmd.batch a bit smarter, by having it flatten any nested batching.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions