0

I am trying to convert the following code to continuation passing style. The code originally returned a String so I changed it to call a continue lambda that takes a String. I am wondering how to remove the next field and use CPS style instead.

class Foo(val x: Double) {
  var next: Foo = _

  def bar(y: Double, returnLambda: (String => Unit)): Unit = {
    if (x * y > 0) {
      returnLambda("Bad")
    } else if (next == null) {
      returnLambda("Good!")
      next = new Foo(y)
    } else {
      next.bar(y, returnLambda)
    }
  }
}
Node.JS
  • 1,042
  • 6
  • 44
  • 114

1 Answers1

1

It looks like you construct a singly-linked list of Foo values; new values are added at the end of the list as long as the signum of the new value is different than an existing value.

In a functional approach, you wouldn't embed list management in an object in the list. Instead, you would maintain a list separately, var next: List[Foo], and perform appending by:

if ( next.all( _ * y <= 0) )
  returnLambda("Bad")
else {
  returnLambda("Good")
  next = next :+ Foo(y)
}

Since we have flattened out the list manipulation, the use of CPS loses its benefit; you could simply return the string "Good" or "Bad".

Assuming that you really, really need the CPS, you can remove the next field by moving it into a companion object:

object Foo {
  val listOfFoo: ListBuffer[Foo] = ListBuffer[Foo].empty

  def bar(y: Double,  returnLambda: (String => Unit)): Unit = 
    if ( listOfFoo.all(_ * y <= 0) )
      returnLambda("Bad")
    else {
      listOfFoo += Foo(y)
      returnLambda("Good")
    }
}
Bob Dalgleish
  • 8,167
  • 4
  • 32
  • 42