Skip to content

all lazy structures are not stack safe #212

@safareli

Description

@safareli

All lazy statures (IO, Future, State) have stack issue. general way of implementing operations on such structures is:

function Structure(f) {
  if (!(this instanceof Structure)) {
    return new Structure(f);
  }
  this.run = f
}

Structure.prototype.method = function (a){
  return new Structure(function(){
    // here we call `run` from a or something like that 
  })
}

All of lazy structures need extra stack frame on each map/ap/chain/..., as they are creating new functions which have use old computation or passed in function, requiring larger stack size, leading to stack overflow (when you run/execute/lower them)

  1. apply curried function f which is taking 10000 arguments:
...(T.of(9999).ap(T.of(10000).ap(T.of(f)))
  1. map on some structure 10000 times
T.of(1).map(id).map(id).map(id).map(id).map(id).....

btw there is no such issue with native Promise:

Array(40000)
  .fill(idx => a=>a + idx)
  .reduce(
    (p,f,idx) => p.then(f(idx)), 
    new Promise((res,rej) => { setTimeout(res, 1000, 1)})
  ).then(console.log.bind(console))// 799980001

General way to fix this would be rewrite such structures so that they builds up computation as data on map/ap/chain/...(like Free monad/applicative...) and executing run interpret it in a stack safe way. For example this way we can make function composition safe. Also related paper "Stack safety for free" by @paf31.

what others think on this issue?

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