VirtusLab / avocADO

Safe compile-time parallelization of for-comprehensions for Scala 3
https://virtuslab.github.io/avocADO/docs/index.html
Apache License 2.0
87 stars 5 forks source link

`dropUnusedMap` implementation #120

Open KacperFKorban opened 2 months ago

KacperFKorban commented 2 months ago

Calling dropUnusedMap with a for comprehension as an argument potentially removed an unused map call at the end of the desugared for, which allows for better stack-safety in FP Scala code.

For example, let's consider the following code:

//> using scala 3.3.3
//> using lib "dev.zio::zio:2.1.5"
//> using lib "org.virtuslab::avocado:0.2.0-a-very-local-SNAPSHOT-not-available-on-maven-yet-since-its-local"

import zio.*
import avocado.*

def loop: Task[Unit] =
//  dropUnusedMap:
    for
      _ <- Console.print("loop")
      _ <- loop
    yield ()

@main
def run =
  val runtime = Runtime.default
  Unsafe.unsafe { implicit unsafe =>
    runtime.unsafe.run(loop).getOrThrowFiberFailure()
  }

It's memory usage looks like this:

image

However, if we uncomment the dropUnusedMap line, the memory usage looks like this:

image

Similar example for cats-effect:

//> using scala 3.3.3
//> using lib "org.typelevel::cats-effect:3.5.4"
//> using lib "org.virtuslab::avocado:0.2.0+3-8e54d976+20240709-1515-SNAPSHOT"

import cats.effect.*
import cats.effect.unsafe.implicits.global
import avocado.*

def loop: IO[Unit] =
//  dropUnusedMap:
    for
      _ <- IO(print("loop"))
      _ <- loop
    yield ()

@main
def run =
  loop.unsafeRunSync()