scalafunctional-programming

Implementing reduce in Scala (Scala FP)


I'm implementing reduce method in Scala as an exercise of Functional Programming in Scala, and I don't think it is running in parallel. How can a create a fully parallel implementation of it?

  def reduce[A](pas: IndexedSeq[A])(f: (A, A) => A): Par[A] =
    if pas.isEmpty then throw new Exception("Can't reduce empty list")
    else if pas.size == 1 then unit(pas.head)
    else
      val (l, r) = pas.splitAt(pas.size / 2)
      reduce(l)(f).map2(reduce(r)(f))(f)

I'm using the Par class from the book:

object Par:
  opaque type Par[A] = ExecutorService => Future[A]

  extension [A](pa: Par[A]) def run(s: ExecutorService): Future[A] = pa(s)

  def fork[A](a: => Par[A]): Par[A] = 
    es => es.submit(new Callable[A] { def call = a(es).get })

  def lazyUnit[A](a: => A): Par[A] = fork(unit(a))

Solution

  • Well, your entire computation finishes without ever forking, so everything runs linearly, nothing runs in parallel. Did you try

    fork(reduce(l)(f)).map2(fork(reduce(r)(f)))(f)
    

    or

    else fork {
      val (l, r) = pas.splitAt(pas.size / 2)
      reduce(l)(f).map2(reduce(r)(f))(f)
    }
    

    ?