purescript / purescript-foreign-object

Functions for working with homogeneous JavaScript objects

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Regression: `Object.fromFoldable` causes stack overflow in Google Chrome

gasi opened this issue · comments

First of all, thanks for all your work on keeping the PureScript ecosystem up and running!


We recently upgraded from PS 0.11 to 0.12 and ran into the following regression Foreign.Object.fromFoldable (vs the old Data.StrMap.fromFoldable) causes a stack overflow for large inputs in Google Chrome (Safari and FF seemed to have higher limits):

❌ Repro: PureScript 0.12

module Main where

import Prelude

import Effect (Effect)
import Effect.Console (log)
import Data.Array ((..))
import Data.Tuple (Tuple(..))
import Foreign.Object as Object

main :: Effect Unit
main = do
  let m = Object.fromFoldable $ do
            x <- 1 .. 10000
            pure $ Tuple (show x) x
  log $ show m

Error

foreign.js:22 Uncaught RangeError: Maximum call stack size exceeded
    at foreign.js:22
    at foreign.js:6
    at foreign.js:20
    at foreign.js:20
    at foreign.js:20
    at foreign.js:20
    at foreign.js:20
    at foreign.js:20
    at foreign.js:20
    at foreign.js:20

✅ PureScript 0.11

Paste this into Try PureScript and observe that there is no stack overflow:

module Main where

import Prelude

import Control.Monad.Eff (Eff)
import Data.Array ((..))
import Data.Tuple (Tuple(..))
import Data.Foldable (fold)
import TryPureScript (DOM, h1, h2, p, text, list, indent, link, render, code)
import Data.StrMap as SM

main :: Eff (dom :: DOM) Unit
main = do
    let m = SM.fromFoldable $ do
              x <- 1 .. 10000
              pure $ Tuple (show x) x
    render $ fold
      [ p (text $ show m) ]

Observations

Superficially the two implementations look the same except the addition of Array.fromFoldable, but I confirmed removing it doesn’t change the outcome:

for_ is never stack safe with ST/Effect, but it was probably consuming less stack before with ST optimizations.