New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Maximum call stack size exceeded" with large List #1521

Closed
jinjor opened this Issue Nov 30, 2016 · 18 comments

Comments

Projects
None yet
@jinjor
Contributor

jinjor commented Nov 30, 2016

This is the same issue as elm/elm-lang.org#671.

If we define a large static list, a runtime error "Maximum call stack size exceeded" occurs on initializing the app.

SSCCE (for Try Elm & Chrome):

import Html exposing (text)

main =
  text "Hello, World!"
  
a =
  [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  ]
  • The max length might change by browsers.
  • A workaround is splitting it into multiple lists like ...,1,1,1] ++ [1,1,1,....

I think this happens more often than 0.17, because I first saw this error during migration to 0.18.

@process-bot

This comment has been minimized.

Show comment
Hide comment
@process-bot

process-bot Nov 30, 2016

Thanks for the issue! Make sure it satisfies this checklist. My human colleagues will appreciate it!

Here is what to expect next, and if anyone wants to comment, keep these things in mind.

process-bot commented Nov 30, 2016

Thanks for the issue! Make sure it satisfies this checklist. My human colleagues will appreciate it!

Here is what to expect next, and if anyone wants to comment, keep these things in mind.

@jsdw

This comment has been minimized.

Show comment
Hide comment
@jsdw

jsdw Dec 6, 2016

I noticed this error recently on 0.17 as well, though only on one person's Firefox (which running the stack size test came out at something like 6000; much less than my browsers). I can't think of any large static arrays or any data processing that would lead to a recursion limit being hit so I'll have to look into it more; I'm worried it'll prove rather hard to find!

jsdw commented Dec 6, 2016

I noticed this error recently on 0.17 as well, though only on one person's Firefox (which running the stack size test came out at something like 6000; much less than my browsers). I can't think of any large static arrays or any data processing that would lead to a recursion limit being hit so I'll have to look into it more; I'm worried it'll prove rather hard to find!

@moore

This comment has been minimized.

Show comment
Hide comment
@moore

moore Dec 9, 2016

I think this is an issue chrome because internally creates a function call to construct a object literal. Ex:
{a:{a:{a:{}}}}
Causes a dept 4 call stack.

Elms list literals in JS are constructed with nested object literals. For lists with thousands of elements evaluating the deeply nested object literal can exceed the stack depth in chrome.

moore commented Dec 9, 2016

I think this is an issue chrome because internally creates a function call to construct a object literal. Ex:
{a:{a:{a:{}}}}
Causes a dept 4 call stack.

Elms list literals in JS are constructed with nested object literals. For lists with thousands of elements evaluating the deeply nested object literal can exceed the stack depth in chrome.

@deepilla

This comment has been minimized.

Show comment
Hide comment
@deepilla

deepilla Dec 11, 2016

It doesn't even take thousands of elements. After upgrading to 0.18, I'm getting this issue with just hundreds of items. I use a list of tuples to initialise a Dict and the code blows up with anything over 475 entries. The same thing happens if I replace the Dict.fromList call with multiple piped calls to Dict.insert. Concatenating several smaller lists seems to work though.

deepilla commented Dec 11, 2016

It doesn't even take thousands of elements. After upgrading to 0.18, I'm getting this issue with just hundreds of items. I use a list of tuples to initialise a Dict and the code blows up with anything over 475 entries. The same thing happens if I replace the Dict.fromList call with multiple piped calls to Dict.insert. Concatenating several smaller lists seems to work though.

@paulswartz

This comment has been minimized.

Show comment
Hide comment
@paulswartz

paulswartz Jan 14, 2017

This doesn't appear to only affect lists: importing Bogdanp/elm-time's Time.TimeZoneData also crashes at runtime with a maximum call-stack error.

paulswartz commented Jan 14, 2017

This doesn't appear to only affect lists: importing Bogdanp/elm-time's Time.TimeZoneData also crashes at runtime with a maximum call-stack error.

@witoldsz

This comment has been minimized.

Show comment
Hide comment
@witoldsz

witoldsz Feb 25, 2017

This doesn't appear to only affect lists: importing Bogdanp/elm-time's Time.TimeZoneData also crashes at runtime with a maximum call-stack error.

It crashes because of list too. There are 600 elements passed to Dict.fromList.

witoldsz commented Feb 25, 2017

This doesn't appear to only affect lists: importing Bogdanp/elm-time's Time.TimeZoneData also crashes at runtime with a maximum call-stack error.

It crashes because of list too. There are 600 elements passed to Dict.fromList.

@bamorim

This comment has been minimized.

Show comment
Hide comment
@bamorim

bamorim Mar 1, 2017

I never messed with the compiler before, but looking at the soure code and at the output
Can't we change the way it creates list ([ ,* ]) to a function that creates the js structure:
like that

function createListFromJSArray(arr){
  if(arr.length == 0){
    return { ctor: '[]' }
  }
  var prev = { ctor: '::', _0: arr[0] }
  var root = prev;
  for(var i = 1; i < arr.length; i++) {
    var curr = { ctor: '::', _0: arr[i] }
    prev._1 = curr
    prev = curr
  }
  prev._1 = { ctor: '[]' }
  return root
}

And then make the compiler generate something like
createListFromJSArray([X,Y,Z,...]) instead of outputing the data tree directly?


Edited to fix code

Edit 2:

Maybe we can just use a self calling function to avoid polluting the global namespace and maybe we should only do that for lists bigger than some length X (and maybe that can be arbitrarily long depending on how browsers change in the future)

bamorim commented Mar 1, 2017

I never messed with the compiler before, but looking at the soure code and at the output
Can't we change the way it creates list ([ ,* ]) to a function that creates the js structure:
like that

function createListFromJSArray(arr){
  if(arr.length == 0){
    return { ctor: '[]' }
  }
  var prev = { ctor: '::', _0: arr[0] }
  var root = prev;
  for(var i = 1; i < arr.length; i++) {
    var curr = { ctor: '::', _0: arr[i] }
    prev._1 = curr
    prev = curr
  }
  prev._1 = { ctor: '[]' }
  return root
}

And then make the compiler generate something like
createListFromJSArray([X,Y,Z,...]) instead of outputing the data tree directly?


Edited to fix code

Edit 2:

Maybe we can just use a self calling function to avoid polluting the global namespace and maybe we should only do that for lists bigger than some length X (and maybe that can be arbitrarily long depending on how browsers change in the future)

teepark added a commit to teepark/elmoji that referenced this issue Mar 1, 2017

teepark added a commit to teepark/elmoji that referenced this issue Mar 4, 2017

Break the long list into several smaller files - Fix stack size probl…
…em in build (#2)

* Split long list into separate lists combined

To address elm/compiler#1521

* Break the long list into even smaller lists

Fixing for use with web pack

* Version Bump
@kuon

This comment has been minimized.

Show comment
Hide comment
@kuon

kuon May 4, 2017

I have this error when decoding a JSON list.

My list is 9914 item long. It decodes fine, and also renders fine once. But as soon as I touch the model (elsewhere) and re-render I got the error.

Stack trace:

app.js:14618 Uncaught RangeError: Maximum call stack size exceeded
    at Function.compare [as func] (app.js:14618)
    at A2 (app.js:13550)
    at Function.func (app.js:16987)
    at A2 (app.js:13550)
    at app.js:22680
    at app.js:13474
    at A2 (app.js:13551)
    at Function.func (app.js:17464)
    at A2 (app.js:13550)
    at Function.func (app.js:17465)

The stack trace is not very helpful, here is the full source:
https://gist.github.com/kuon/005e7ebff78a9488243e652479b60eaf

kuon commented May 4, 2017

I have this error when decoding a JSON list.

My list is 9914 item long. It decodes fine, and also renders fine once. But as soon as I touch the model (elsewhere) and re-render I got the error.

Stack trace:

app.js:14618 Uncaught RangeError: Maximum call stack size exceeded
    at Function.compare [as func] (app.js:14618)
    at A2 (app.js:13550)
    at Function.func (app.js:16987)
    at A2 (app.js:13550)
    at app.js:22680
    at app.js:13474
    at A2 (app.js:13551)
    at Function.func (app.js:17464)
    at A2 (app.js:13550)
    at Function.func (app.js:17465)

The stack trace is not very helpful, here is the full source:
https://gist.github.com/kuon/005e7ebff78a9488243e652479b60eaf

@bamorim

This comment has been minimized.

Show comment
Hide comment
@bamorim

bamorim May 4, 2017

@kuon I don't think this is the same issue. This issue was caused when initializing a big list in elm due to how the elm compiler created the JS code to instantiate the list. In your case this is probably being caused by something else, but it will be hard to know what without the source code. Looking at the compiled code, that may be something related to Dict. Are you creating a Dict from this list?

bamorim commented May 4, 2017

@kuon I don't think this is the same issue. This issue was caused when initializing a big list in elm due to how the elm compiler created the JS code to instantiate the list. In your case this is probably being caused by something else, but it will be hard to know what without the source code. Looking at the compiled code, that may be something related to Dict. Are you creating a Dict from this list?

@kuon

This comment has been minimized.

Show comment
Hide comment
@kuon

kuon May 4, 2017

Ok, after tinkering and help from slack, my issue appears to be caused by the debugger.

kuon commented May 4, 2017

Ok, after tinkering and help from slack, my issue appears to be caused by the debugger.

@andys8

This comment has been minimized.

Show comment
Hide comment
@andys8

andys8 May 22, 2017

Contributor

We suffer from this issue, too. The compiler will generate a large javascript file containing lots of empty lines (I think spaces).

Contributor

andys8 commented May 22, 2017

We suffer from this issue, too. The compiler will generate a large javascript file containing lots of empty lines (I think spaces).

magopian added a commit to mozilla-services/buildhub that referenced this issue Jun 2, 2017

n1k0 added a commit to mozilla-services/buildhub that referenced this issue Jun 2, 2017

@Steve-OH

This comment has been minimized.

Show comment
Hide comment
@Steve-OH

Steve-OH Jun 6, 2017

@kuon

Do you have more info regarding this problem? I'm experiencing the same thing, also with large JSON lists. Did you come up with a workaround that still allows the debugger to run?

Steve-OH commented Jun 6, 2017

@kuon

Do you have more info regarding this problem? I'm experiencing the same thing, also with large JSON lists. Did you come up with a workaround that still allows the debugger to run?

@kuon

This comment has been minimized.

Show comment
Hide comment
@kuon

kuon Jun 6, 2017

@Steve-OH turned the debugger off for now, I'd be interested in a better solution too

kuon commented Jun 6, 2017

@Steve-OH turned the debugger off for now, I'd be interested in a better solution too

@Steve-OH

This comment has been minimized.

Show comment
Hide comment
@Steve-OH

Steve-OH Jun 7, 2017

@kuon

Ah, well. I figured as much. Thanks.

Steve-OH commented Jun 7, 2017

@kuon

Ah, well. I figured as much. Thanks.

@b0urb4k1

This comment has been minimized.

Show comment
Hide comment
@b0urb4k1

b0urb4k1 Sep 27, 2017

I am suffering from a similar problem with about 10000 entries in a list. When the lists of my model contain less entries everything works as intended. The problem here seems to be the comparison function. This prevents me from even returning the same model in the update function.

TestView.elm:1381 Uncaught RangeError: Maximum call stack size exceeded
at Object.cmp (TestView.elm:1381)
at Function.compare [as func] (TestView.elm:1162)
at A2 (TestView.elm:92)
at Function.func (TestView.elm:3529)
at A2 (TestView.elm:92)
at TestView.elm:9222
at TestView.elm:16
at A2 (TestView.elm:93)
at Function.func (TestView.elm:4006)
at A2 (TestView.elm:92)

If there is a workaround please let me know, i tried to switch to Arrays the problem still remains (maybe because the comparison is done in the DOM part behind the scenes?).

b0urb4k1 commented Sep 27, 2017

I am suffering from a similar problem with about 10000 entries in a list. When the lists of my model contain less entries everything works as intended. The problem here seems to be the comparison function. This prevents me from even returning the same model in the update function.

TestView.elm:1381 Uncaught RangeError: Maximum call stack size exceeded
at Object.cmp (TestView.elm:1381)
at Function.compare [as func] (TestView.elm:1162)
at A2 (TestView.elm:92)
at Function.func (TestView.elm:3529)
at A2 (TestView.elm:92)
at TestView.elm:9222
at TestView.elm:16
at A2 (TestView.elm:93)
at Function.func (TestView.elm:4006)
at A2 (TestView.elm:92)

If there is a workaround please let me know, i tried to switch to Arrays the problem still remains (maybe because the comparison is done in the DOM part behind the scenes?).

@zwilias

This comment has been minimized.

Show comment
Hide comment
@zwilias

zwilias Sep 27, 2017

Member

@b0urb4k1 : you're facing a different (non-compiler related) issue, more specifically https://github.com/elm-lang/virtual-dom/issues/80 (tracked in https://github.com/elm-lang/virtual-dom/issues/98)

The current suggestion, until that is fixed, is to turn off the debugger or use a smaller dataset during development.

Thanks for the report!

Member

zwilias commented Sep 27, 2017

@b0urb4k1 : you're facing a different (non-compiler related) issue, more specifically https://github.com/elm-lang/virtual-dom/issues/80 (tracked in https://github.com/elm-lang/virtual-dom/issues/98)

The current suggestion, until that is fixed, is to turn off the debugger or use a smaller dataset during development.

Thanks for the report!

@Janjuks

This comment has been minimized.

Show comment
Hide comment
@Janjuks

Janjuks Dec 5, 2017

Happens to me too on Chrome Version 62.0.3202.94 (Official Build) (64-bit)
Works fine on Edge 40.15063.674.0.

Was trying to create 1058 long list of integers.

Elm 0.18

Janjuks commented Dec 5, 2017

Happens to me too on Chrome Version 62.0.3202.94 (Official Build) (64-bit)
Works fine on Edge 40.15063.674.0.

Was trying to create 1058 long list of integers.

Elm 0.18

Zinggi pushed a commit to Zinggi/elm-hash-icon that referenced this issue Mar 2, 2018

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Mar 7, 2018

Member

The root issue seems to be that the generated code represents things faithfully as they will be at runtime. A bunch of nested cons cells.

In my development build, we no longer do the cons representation of the list. Instead, it is a JS array that gets converted at runtime. This is how it was before this issue started appearing, and it is just going back to how it used to be.

Member

evancz commented Mar 7, 2018

The root issue seems to be that the generated code represents things faithfully as they will be at runtime. A bunch of nested cons cells.

In my development build, we no longer do the cons representation of the list. Instead, it is a JS array that gets converted at runtime. This is how it was before this issue started appearing, and it is just going back to how it used to be.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment