scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

Add support for CPS to Actor/Future #781

Closed scabug closed 13 years ago

scabug commented 16 years ago

Using actors with asynchronous operations can currently result in messy code when compared to using synchronous operations. This is because it is often necessary to nest the continuations for each reaction, even when the logic is basically linear.

eg

val x = adder !? Add(1, 2)
val y = adder !? Add(3, 4)
val z = adder !? Add(x.asInstanceOf[Int], y.asInstanceOf[Int])
println("Sum is: " + z)

vs

adder ! Add(1, 2)
react {
  case x => {
    adder ! Add(3, 4)
    react {
      case y => {
    adder ! Add(x.asInstanceOf[Int], y.asInstanceOf[Int])
    react {
      case z => {
        println("Sum is: " + z)
      }
    }
      }
    }
  }
}

However, using Responders and for comprehensions can make a continuation-passing style much clearer. The following patch adds support for Responders to the Actor class.

eg

Responder.run {
  for (
    x <- adder !% Add(1, 2);
    y <- adder !% Add(3, 4);
    z <- adder !% Add(x.asInstanceOf[Int], y.asInstanceOf[Int]);
    _ <- exec(println("Sum is: " + z))
  ) yield ()
}
scabug commented 16 years ago

Imported From: https://issues.scala-lang.org/browse/SI-781?orig=1 Reporter: @richdougherty Attachments:

scabug commented 16 years ago

@phaller said: Examples of Responder-based actors.

scabug commented 16 years ago

@phaller said: Adding support for writing actors using Responders has been discussed for a long time now. (See for example http://article.gmane.org/gmane.comp.lang.scala.user/1350/.)

In r14801 I committed initial support for that. It generalizes the proposals discussed in the mailing list thread referenced above by introducing the async method (not sure whether the name is ideal). This method can be used to make methods like react usable inside Responders. I attach the source code for some examples that demonstrates the usage.

For convenience there is also a reactor factory method for creating Responder-based actors. It takes a Responder as argument.

An idea that I like is to make Futures into Responders. Note that this makes the !% method that you propose obsolete: your above example can be written as follows:

val a = reactor {
  for {
    x <- adder !! Add(1, 2);
    y <- adder !! Add(3, 4);
    z <- adder !! Add(x.asInstanceOf[Int], y.asInstanceOf[Int]);
    if   exec(println("Sum is: " + z))
  } yield {}
}

I invite people to try out this extension, and give feedback on the mailing lists.

I close this ticket now.

scabug commented 16 years ago

@richdougherty said: Looks good, thanks.

scabug commented 15 years ago

@odersky said: Milestone next_bugfix deleted