alexmingoia / purescript-pux

Build type-safe web apps with PureScript.
https://www.purescript-pux.org
Other
566 stars 76 forks source link

Rendering large numbers of elements exceeds maximum call depth #138

Closed thomashoneyman closed 7 years ago

thomashoneyman commented 7 years ago

Hi Alex!

I have recently encountered an issue with Smolder where traversing a large array of elements will fail by exceeding the maximum call depth in Javascript. This happens because the MarkupM monad doesn't have an instance of MonadRec, and so (to my knowledge) you can't do stack-safe traversals within the monad -- monads in Purescript don't, by default, end up as tail-recursive Javascript.

A full description of the issue, and a minimal GitHub repo that reproduces the issue (and shows that traversing and logging all the elements works, but rendering fails) are here:

purescript-smolder - Issues - 29

If I am in a situation where I would like to be able to perform a stack-safe traversal when rendering elements to the DOM, it seems like there are a few possibilities:

  1. Use Halogen's HTML renderer, which uses trees of arrays and is stack safe
  2. Possibly try and implement a Free monad over the MarkupM monad (suggested by @syaiful6 on Gitter)
  3. Use another workaround with Smolder

I know there are other solutions, like windowed rendering, that help lessen the need to render so many elements at once.

Even so, my ultimate goal is to do a stack-safe traversal to render an array of elements in HTML; combining that with windowed rendering or other solutions is nice bonus. And I'd love to do this with Pux, which I've thoroughly enjoyed using on a few projects so far.

All the best, Thomas

thomashoneyman commented 7 years ago

Bodil Stokke has released a new update to Smolder that fixes this issue, v10.0:

https://github.com/bodil/purescript-smolder/issues/29

It looks like this can be fixed by bumping Pux to use purescript-smolder 10.0 instead of 9.0

thomashoneyman commented 7 years ago

With the merge to Smolder v10, this is solved.