Skip to content

ManagedResource.map() is not stack safe #65

Open
@underspecified

Description

@underspecified

Greetings,

I have been using scala-arm to read and concatenate lines from a large number of files, an operation that requires a large number of nested calls to ManagedResource.map(). This appears to trigger a stack overflow at somewhere between 1,000 and 10,000 nested calls. Here is a trivial reproduction:

import resource._
import scala.math.BigInt._

// calculate factorial inside of Scala Option
def factorialO(max: Int): Option[BigInt] = {
  val z: Option[BigInt] = Option(1)
  (1 to max).foldLeft(z) { (b,a) => b.map(_ * a) }
}

// calculate factorial inside of ManagedResource
def factorialR(max: Int): ManagedResource[BigInt] = {
  val z: ManagedResource[BigInt] = new ConstantManagedResource(1)
  (1 to max).foldLeft(z) { (b,a) => b.map(_ * a) }
}

// Some(93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000)                  
println(factorialO(100))

// 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000                        
println(factorialR(100).acquireAndGet(x => x))

// prints really big number                                                                                                                                                              
println(factorialO(10000))

// java.lang.StackOverflowError                                                                                                                                                          
//println(factorialR(10000).acquireAndGet(x => x))                                                                                                                                       

It seems the solution is to define map() and flatMap() using trampolines like is done in Scala Cats, or am I missing something?

All the best,
-underspecified

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions