This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Actor: super.receive(f) works, super.receive(idFun andThen f) causes scala.MatchError

11 replies
Stefan Kuhn
Joined: 2009-10-01,
User offline. Last seen 42 years 45 weeks ago.

trait Logtor extends Actor ... {

val idFun : PartialFunction[Any, Any]= { case x => x}

abstract override def receive[R](f: PartialFunction[Any, R]): R = {
// super.receive(f) // <<< no error
super.receive(idFun andThen f) // <<< error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError:
//PivotedSlice(2,X)
}

The error is non-deterministic but reproducible.
Tests exist which always produced the error.

Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/exp...

Testsuite is at:
Sbt_2.8/
src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala

It's Scala RC3. The project is build with SBT with managed libs only.

Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.

Thanks in advance
stefan

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Actor: super.receive(f) works, super.receive(idFun andThen
Hello Stefan,

just to provide an alternative solution: AKKA - http://github.com/jboner/akka/blob/master/akka-core/src/main/scala/routing/Patterns.scala#L51

On Wed, Jun 9, 2010 at 11:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote:
trait Logtor extends Actor ... {

val idFun : PartialFunction[Any, Any]= { case x => x}

abstract override def receive[R](f: PartialFunction[Any, R]): R = {
//    super.receive(f)  //  <<< no error
     super.receive(idFun andThen f) //  <<<  error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError: //PivotedSlice(2,X)
}

The error is non-deterministic but reproducible.
Tests exist which always produced the error.

Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/experimental/Logtor.scala

Testsuite is at:
Sbt_2.8/ src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala

It's Scala RC3. The project is build with SBT with managed libs only.

Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.


Thanks in advance
       stefan



Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Actor: super.receive(f) works, super.receive(idFun andThen


On Thu, Jun 10, 2010 at 9:44 AM, Viktor Klang <viktor.klang@gmail.com> wrote:
Hello Stefan,

just to provide an alternative solution: AKKA - http://github.com/jboner/akka/blob/master/akka-core/src/main/scala/routing/Patterns.scala#L51

Sorry, too specific link, should be: http://github.com/jboner/akka/blob/master/akka-core/src/main/scala/routing/Patterns.scala
 


On Wed, Jun 9, 2010 at 11:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote:
trait Logtor extends Actor ... {

val idFun : PartialFunction[Any, Any]= { case x => x}

abstract override def receive[R](f: PartialFunction[Any, R]): R = {
//    super.receive(f)  //  <<< no error
     super.receive(idFun andThen f) //  <<<  error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError: //PivotedSlice(2,X)
}

The error is non-deterministic but reproducible.
Tests exist which always produced the error.

Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/experimental/Logtor.scala

Testsuite is at:
Sbt_2.8/ src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala

It's Scala RC3. The project is build with SBT with managed libs only.

Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.


Thanks in advance
       stefan



Philipp Haller
Joined: 2009-01-13,
User offline. Last seen 42 years 45 weeks ago.
Re: Actor: super.receive(f) works, super.receive(idFun andThen

Hi,

I haven't been able to reproduce it. A small self-contained example
would help.

Cheers,
Philipp

On 06/09/2010 11:35 PM, Stefan Kuhn wrote:
> trait Logtor extends Actor ... {
>
> val idFun : PartialFunction[Any, Any]= { case x => x}
>
> abstract override def receive[R](f: PartialFunction[Any, R]): R = {
> // super.receive(f) //<<< no error
> super.receive(idFun andThen f) //<<< error!!!
> //thesis.bsps.sort.WorkerNode@X: caught scala.MatchError:
> //PivotedSlice(2,X)
> }
>
> The error is non-deterministic but reproducible.
> Tests exist which always produced the error.
>
> Switch Line 16 vs 17 to see.
> http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/exp...
>
> Testsuite is at:
> Sbt_2.8/
> src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala
>
> It's Scala RC3. The project is build with SBT with managed libs only.
>
> Any ideas what's wrong?
> By the way, the app sorts distributed, with RegularSampling / PSRS.
>
>
> Thanks in advance
> stefan
>
>
>
> ----- stack trace -----
> thesis.bsps.sort.WorkerNode@250d593e: caught scala.MatchError:
> PivotedSlice(0,[I@6f649b44)
> scala.MatchError: PivotedSlice(0,[I@6f649b44)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$3.apply(RegularSamplingScalaActors.scala:126)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$3.apply(RegularSamplingScalaActors.scala:126)
> at scala.PartialFunction$$anon$2.apply(PartialFunction.scala:58)
> at scala.actors.Actor$class.receive(Actor.scala:487)
> at
> thesis.bsps.sort.WorkerNode.thesis$experimental$Logtor$$super$receive(RegularSamplingScalaActors.scala:95)
> at thesis.experimental.Logtor$class.receive(Logtor.scala:17)
> at thesis.bsps.sort.WorkerNode.receive(RegularSamplingScalaActors.scala:95)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply$mcV$sp(RegularSamplingScalaActors.scala:103)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply(RegularSamplingScalaActors.scala:103)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply(RegularSamplingScalaActors.scala:103)
> at scala.actors.Reactor$class.seq(Reactor.scala:280)
> at thesis.bsps.sort.WorkerNode.seq(RegularSamplingScalaActors.scala:95)
> at scala.actors.Reactor$$anon$3.andThen(Reactor.scala:258)
> at scala.actors.Combinators$class.loop(Combinators.scala:26)
> at thesis.bsps.sort.WorkerNode.loop(RegularSamplingScalaActors.scala:95)
> at scala.actors.Combinators$$anonfun$loop$1.apply(Combinators.scala:26)
> at scala.actors.Combinators$$anonfun$loop$1.apply(Combinators.scala:26)
> at
> scala.actors.Reactor$$anonfun$seq$1$$anonfun$apply$1.apply(Reactor.scala:277)
> at scala.actors.ReactorTask.run(ReactorTask.scala:34)
> at scala.actors.ReactorTask.compute(ReactorTask.scala:66)
> at scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:147)
> at
> scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
> at
> scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)
> at
> scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325)
>
>
>
>
>
>

Stefan Kuhn
Joined: 2009-10-01,
User offline. Last seen 42 years 45 weeks ago.
Re: Actor: super.receive(f) works, super.receive(idFun andThen f

I've stripped my example down to 130 LOCs. Is that good enough?

It's here
http://paste.pocoo.org/show/223927/

Or here ;)

-------------------------------

package thesis.bugs.scalaActors

import scala.actors.Actor, Actor._

trait LoggingActor extends Actor {
val shouldUseIdFun :Boolean
val idFun : PartialFunction[Any, Any]= { case x => x}
abstract override def receive[R](f: PartialFunction[Any, R]): R = {
if(shouldUseIdFun)
super.receive(idFun andThen f) //error
else
super.receive(f)
}
}

object IdFunProblem {
def main(args :Array[String]) {
println("Start without idFun")
var shouldUseIdFun = false
for(i <- 0 to 1000){
run(5,shouldUseIdFun)
}
println("Start WITH idFun")
shouldUseIdFun = true
for(i <- 0 to 1000){
run(5,shouldUseIdFun)
}
println("Done")
}

def run( p :Int, shouldUseIdFun :Boolean) {
val workers = (new Array[Actor](p)).zipWithIndex.map(x => new
WorkerNode(shouldUseIdFun, x._2))
workers.map(_.start)
val controller = new Controller(workers)
controller.start
val futResponse = controller !! StartController()
val result = futResponse()
}
}

sealed trait RegularSamplingMsg
case class StartController() extends RegularSamplingMsg
case class InitSlice[T <: Actor](coWorkers :Array[T], controller :Actor)
extends RegularSamplingMsg
case class Samples(fromID :Int) extends RegularSamplingMsg
case class Pivots(controller :Actor) extends RegularSamplingMsg
case class PivotedSlice(fromID :Int) extends RegularSamplingMsg
case class Result(fromID :Int) extends RegularSamplingMsg

import scala.actors.OutputChannel
class Controller[T <: Actor](workers :Array[T]) extends Actor {
sealed trait State
case object Init extends State
case class WaitingForSamples(var remaining :Int, sender
:OutputChannel[Any]) extends State
case class WaitingForResults(var remaining :Int, sender
:OutputChannel[Any]) extends State

var state :State = Init
val p = workers.size

def act = { loop { receive {
case StartController() => {
for(i <- 0 until p){
workers(i) ! InitSlice( workers, self)
}
state = WaitingForSamples(p, sender)
}

case Samples(from) => {
val sampleState = state.asInstanceOf[WaitingForSamples]
sampleState.remaining -= 1
if(sampleState.remaining == 0){
workers.map(_ ! Pivots( self))
state = new WaitingForResults(p,sampleState.sender )
}
}

case Result(from) => {
val resultState = state.asInstanceOf[WaitingForResults]
resultState.remaining -= 1
if(resultState.remaining == 0){
resultState.sender ! Array(1)
exit
}
}

}}}
}

class WorkerNode(val shouldUseIdFun :Boolean, id :Int) extends Actor
with LoggingActor {
type M = PartialFunction[Any,Unit]
sealed trait State
case object Init extends State
case class WaitingForPivots(coWorkers :Array[Actor],controller
:Actor) extends State
case class WaitingForPivotedSlices(var remaining :Int, controller
:Actor) extends State

var state :State = Init
def act = { loop { receive {
state match { //more elegant with direct state switch?
case Init =>
initFun
case _:WaitingForPivots =>
pivotFun
case _:WaitingForPivotedSlices =>
pivotSliceFun
case x =>
throw new IllegalStateException(id+") in state("+state+")
received: "+x)
}
}}}

val initFun :M = {
case InitSlice( coWorkers, controller) => {
val p = coWorkers.size
controller ! Samples(id)
state = WaitingForPivots( coWorkers, controller)
}
}

val pivotFun :M = {
case Pivots(controller) => {
val gotSliceState = state.asInstanceOf[WaitingForPivots]
val coWorkers = gotSliceState.coWorkers
val p = coWorkers.size
for(i <- 0 until p){
coWorkers(i) ! PivotedSlice(id)
}
state = WaitingForPivotedSlices(p, controller)
}
}

val pivotSliceFun :M = {
case PivotedSlice( slice) => {
val waitingState = state.asInstanceOf[WaitingForPivotedSlices]
waitingState.remaining -= 1
if(waitingState.remaining == 0){
waitingState.controller ! Result(id)
exit
}
}
}
}

Stefan Kuhn
Joined: 2009-10-01,
User offline. Last seen 42 years 45 weeks ago.
Re: Actor: super.receive(f) works, super.receive(idFun andThen f

I've cut it further down

http://paste.pocoo.org/show/225263/

-stefan

----

package thesis.bugs.scalaActors

import scala.actors.Actor, Actor._, State._

trait LoggingActor extends Actor {
val shouldUseIdFun :Boolean
val idFun : PartialFunction[Any, Any]= { case x => x}
abstract override def receive[R](f: PartialFunction[Any, R]): R = {
if(shouldUseIdFun)
super.receive(idFun andThen f) //error
else
super.receive(f)
}
}

object IdFunProblem {
def main(args :Array[String]) {
println("Start without idFun")
var shouldUseIdFun = false
run(5,shouldUseIdFun)
println("Start WITH idFun")
shouldUseIdFun = true
for(i <- 0 to 5){
print("\n"+i+") ")
run(5,shouldUseIdFun)
}
println("Done")
}

def run( p :Int, shouldUseIdFun :Boolean) {
val workers = (new Array[Actor](p)).zipWithIndex.map(x => new
WorkerNode(shouldUseIdFun, x._2))
workers.map(_.start)
val controller = new Controller(workers)
controller.start
while (controller.getState != Terminated)
Thread.`yield`
}
}

sealed trait RegularSamplingMsg
case class Task[T <: Actor](coWorkers :Array[T], controller :Actor)
extends RegularSamplingMsg
case object TaskResult extends RegularSamplingMsg
case class Result(fromID :Int) extends RegularSamplingMsg

import scala.actors.OutputChannel
/**
* Controller sends N Workers a Tasks.
* Each Worker sends each Worker TaskResults.
* After a worker received N TaskResults it sends Result to the Controller
*
*/
class Controller[T <: Actor](workers :Array[T]) extends Actor {

val p = workers.size

def act = {
for(i <- 0 until p){
workers(i) ! Task( workers, self)
}
var waitingForNResults = p
loop { receive {

case Result(from) => {
waitingForNResults -= 1
if(waitingForNResults == 0){
exit
}
}

}}}
}

class WorkerNode(val shouldUseIdFun :Boolean, id :Int) extends Actor
with LoggingActor {
type M = PartialFunction[Any,Unit]
sealed trait State
case object WaitingForTask extends State
case class WaitingForTaskResults(var remaining :Int, controller
:Actor) extends State

var state :State = WaitingForTask
def act = { loop { receive {
state match { //more elegant with direct state switch?
case WaitingForTask =>
initFun
case _:WaitingForTaskResults =>
collectTaskResults
case x =>
throw new IllegalStateException(id+") in state("+state+")")
}
}}}

val initFun :M = {
case Task( coWorkers, controller) => {
val p = coWorkers.size
for(i <- 0 until p){
coWorkers(i) ! TaskResult
}
state = WaitingForTaskResults(p, controller)
}
}

val collectTaskResults :M = {
case TaskResult => {
val waitingState = state.asInstanceOf[WaitingForTaskResults]
waitingState.remaining -= 1
if(waitingState.remaining == 0){
waitingState.controller ! Result(id)
exit
}
}
}
}

Am 10.06.10 14:04, schrieb Philipp Haller:
> Hi,
>
> I haven't been able to reproduce it. A small self-contained example
> would help.
>
> Cheers,
> Philipp
>
>
> On 06/09/2010 11:35 PM, Stefan Kuhn wrote:
>> trait Logtor extends Actor ... {
>>
>> val idFun : PartialFunction[Any, Any]= { case x => x}
>>
>> abstract override def receive[R](f: PartialFunction[Any, R]): R = {
>> // super.receive(f) //<<< no error
>> super.receive(idFun andThen f) //<<< error!!!
>> //thesis.bsps.sort.WorkerNode@X: caught scala.MatchError:
>> //PivotedSlice(2,X)
>> }
>>
>> The error is non-deterministic but reproducible.
>> Tests exist which always produced the error.
>>
>> Switch Line 16 vs 17 to see.
>> http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/exp...
>>
>>
>> Testsuite is at:
>> Sbt_2.8/
>> src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala
>>
>> It's Scala RC3. The project is build with SBT with managed libs only.
>>
>> Any ideas what's wrong?
>> By the way, the app sorts distributed, with RegularSampling / PSRS.
>>
>>
>> Thanks in advance
>> stefan
>>
>>
>>
>> ----- stack trace -----
>> thesis.bsps.sort.WorkerNode@250d593e: caught scala.MatchError:
>> PivotedSlice(0,[I@6f649b44)
>> scala.MatchError: PivotedSlice(0,[I@6f649b44)
>> at
>> thesis.bsps.sort.WorkerNode$$anonfun$3.apply(RegularSamplingScalaActors.scala:126)
>>
>> at
>> thesis.bsps.sort.WorkerNode$$anonfun$3.apply(RegularSamplingScalaActors.scala:126)
>>
>> at scala.PartialFunction$$anon$2.apply(PartialFunction.scala:58)
>> at scala.actors.Actor$class.receive(Actor.scala:487)
>> at
>> thesis.bsps.sort.WorkerNode.thesis$experimental$Logtor$$super$receive(RegularSamplingScalaActors.scala:95)
>>
>> at thesis.experimental.Logtor$class.receive(Logtor.scala:17)
>> at
>> thesis.bsps.sort.WorkerNode.receive(RegularSamplingScalaActors.scala:95)
>> at
>> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply$mcV$sp(RegularSamplingScalaActors.scala:103)
>>
>> at
>> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply(RegularSamplingScalaActors.scala:103)
>>
>> at
>> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply(RegularSamplingScalaActors.scala:103)
>>
>> at scala.actors.Reactor$class.seq(Reactor.scala:280)
>> at thesis.bsps.sort.WorkerNode.seq(RegularSamplingScalaActors.scala:95)
>> at scala.actors.Reactor$$anon$3.andThen(Reactor.scala:258)
>> at scala.actors.Combinators$class.loop(Combinators.scala:26)
>> at thesis.bsps.sort.WorkerNode.loop(RegularSamplingScalaActors.scala:95)
>> at scala.actors.Combinators$$anonfun$loop$1.apply(Combinators.scala:26)
>> at scala.actors.Combinators$$anonfun$loop$1.apply(Combinators.scala:26)
>> at
>> scala.actors.Reactor$$anonfun$seq$1$$anonfun$apply$1.apply(Reactor.scala:277)
>>
>> at scala.actors.ReactorTask.run(ReactorTask.scala:34)
>> at scala.actors.ReactorTask.compute(ReactorTask.scala:66)
>> at
>> scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:147)
>> at
>> scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
>> at
>> scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)
>>
>> at
>> scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325)
>>
>>
>>
>>
>>
>>
>>
>
>

Stefan Kuhn
Joined: 2009-10-01,
User offline. Last seen 42 years 45 weeks ago.
Re: Actor: super.receive(f) works, super.receive(idFun andThen f

To make it more comprehensive, I've added the error at the very end of
the sources:
http://paste.pocoo.org/show/225312/

Why does super.receive(idFun andThen f) instead of super.receive(f)
changes the behaviour?

Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: Actor: super.receive(f) works, super.receive(idFun andThen
Since no one else tackled this:
You're using Partial Functions improperly.   That being, if you want to combine PartialFunctions, andThen will compose them.   However, it assumes that each one *completely* matches the space, or throws an error.
If you want to join them "case-wise" so-to-speak you want to use the orElse function.   When combining receive methods from an actor hierarchy, orElse is how you need to do it, unless you want the first function to be the only thing that has a chance to match against the input.
- Josh
P.S. - Not sure what variant of Scala you're using, but the code you posted is quite... uncompilable for me.

On Wed, Jun 9, 2010 at 5:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote:
trait Logtor extends Actor ... {

val idFun : PartialFunction[Any, Any]= { case x => x}

abstract override def receive[R](f: PartialFunction[Any, R]): R = {
//    super.receive(f)  //  <<< no error
     super.receive(idFun andThen f) //  <<<  error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError: //PivotedSlice(2,X)
}

The error is non-deterministic but reproducible.
Tests exist which always produced the error.

Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/experimental/Logtor.scala

Testsuite is at:
Sbt_2.8/ src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala

It's Scala RC3. The project is build with SBT with managed libs only.

Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.


Thanks in advance
       stefan



Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Actor: super.receive(f) works, super.receive(idFun andThen


On Mon, Jun 14, 2010 at 5:43 PM, Josh Suereth <joshua.suereth@gmail.com> wrote:
Since no one else tackled this:

Erm, I sent a link to an implementation of a logging actor :p
Also, in the link was sample code to do PartialFunction filter and intercept
 

You're using Partial Functions improperly.   That being, if you want to combine PartialFunctions, andThen will compose them.   However, it assumes that each one *completely* matches the space, or throws an error.
If you want to join them "case-wise" so-to-speak you want to use the orElse function.   When combining receive methods from an actor hierarchy, orElse is how you need to do it, unless you want the first function to be the only thing that has a chance to match against the input.
- Josh
P.S. - Not sure what variant of Scala you're using, but the code you posted is quite... uncompilable for me.

On Wed, Jun 9, 2010 at 5:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote:
trait Logtor extends Actor ... {

val idFun : PartialFunction[Any, Any]= { case x => x}

abstract override def receive[R](f: PartialFunction[Any, R]): R = {
//    super.receive(f)  //  <<< no error
     super.receive(idFun andThen f) //  <<<  error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError: //PivotedSlice(2,X)
}

The error is non-deterministic but reproducible.
Tests exist which always produced the error.

Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/experimental/Logtor.scala

Testsuite is at:
Sbt_2.8/ src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala

It's Scala RC3. The project is build with SBT with managed libs only.

Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.


Thanks in advance
       stefan



Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: Actor: super.receive(f) works, super.receive(idFun andThen
My bad! no harm meant.

On Mon, Jun 14, 2010 at 11:51 AM, Viktor Klang <viktor.klang@gmail.com> wrote:


On Mon, Jun 14, 2010 at 5:43 PM, Josh Suereth <joshua.suereth@gmail.com> wrote:
Since no one else tackled this:

Erm, I sent a link to an implementation of a logging actor :p
Also, in the link was sample code to do PartialFunction filter and intercept
 

You're using Partial Functions improperly.   That being, if you want to combine PartialFunctions, andThen will compose them.   However, it assumes that each one *completely* matches the space, or throws an error.
If you want to join them "case-wise" so-to-speak you want to use the orElse function.   When combining receive methods from an actor hierarchy, orElse is how you need to do it, unless you want the first function to be the only thing that has a chance to match against the input.
- Josh
P.S. - Not sure what variant of Scala you're using, but the code you posted is quite... uncompilable for me.

On Wed, Jun 9, 2010 at 5:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote:
trait Logtor extends Actor ... {

val idFun : PartialFunction[Any, Any]= { case x => x}

abstract override def receive[R](f: PartialFunction[Any, R]): R = {
//    super.receive(f)  //  <<< no error
     super.receive(idFun andThen f) //  <<<  error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError: //PivotedSlice(2,X)
}

The error is non-deterministic but reproducible.
Tests exist which always produced the error.

Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/experimental/Logtor.scala

Testsuite is at:
Sbt_2.8/ src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala

It's Scala RC3. The project is build with SBT with managed libs only.

Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.


Thanks in advance
       stefan



Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: Actor: super.receive(f) works, super.receive(idFun andThen
Also, as I stated in #scala, the issue is more that isDefinedAt in the andThen function is essentially *exactly* the same as the first function's andThen.   You'll have to manually override this.
- Josh

On Mon, Jun 14, 2010 at 11:43 AM, Josh Suereth <joshua.suereth@gmail.com> wrote:
Since no one else tackled this:
You're using Partial Functions improperly.   That being, if you want to combine PartialFunctions, andThen will compose them.   However, it assumes that each one *completely* matches the space, or throws an error.
If you want to join them "case-wise" so-to-speak you want to use the orElse function.   When combining receive methods from an actor hierarchy, orElse is how you need to do it, unless you want the first function to be the only thing that has a chance to match against the input.
- Josh
P.S. - Not sure what variant of Scala you're using, but the code you posted is quite... uncompilable for me.

On Wed, Jun 9, 2010 at 5:35 PM, Stefan Kuhn <qn.666@gmx.net> wrote:
trait Logtor extends Actor ... {

val idFun : PartialFunction[Any, Any]= { case x => x}

abstract override def receive[R](f: PartialFunction[Any, R]): R = {
//    super.receive(f)  //  <<< no error
     super.receive(idFun andThen f) //  <<<  error!!!
//thesis.bsps.sort.WorkerNode@X: caught scala.MatchError: //PivotedSlice(2,X)
}

The error is non-deterministic but reproducible.
Tests exist which always produced the error.

Switch Line 16 vs 17 to see.
http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/experimental/Logtor.scala

Testsuite is at:
Sbt_2.8/ src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala

It's Scala RC3. The project is build with SBT with managed libs only.

Any ideas what's wrong?
By the way, the app sorts distributed, with RegularSampling / PSRS.


Thanks in advance
       stefan



Stefan Kuhn
Joined: 2009-10-01,
User offline. Last seen 42 years 45 weeks ago.
Re: Actor: super.receive(f) works, super.receive(idFun andThen

Thanks, problem solved.

For the record:
My problem was the idDefinedAt result of idFun andThen f. It is first
suprising, because if idFun andThen f results in f(idFun(x)) I expected
that isDefinedAt of the resulting function tests if idFun isDefinedAt x
&& f isDefinedAt idFun(x). Because of possible sideeffects in idFun, it
does make sense.

Still suprising.

trait LoggingActor extends Actor {
val shouldUseIdFun :Boolean
abstract override def receive[R](f: PartialFunction[Any, R]): R = {
if(shouldUseIdFun)
super.receive(idFun2(f))
else
super.receive(f)
}

def idFun2[R](f: PartialFunction[Any, R]): PartialFunction[Any, R] = {
new PartialFunction[Any, R] {
def isDefinedAt(x: Any): Boolean = f.isDefinedAt(x)
def apply(x: Any): R = {
f(x)
}
}
}
}

Am 14.06.10 17:43, schrieb Josh Suereth:
> Since no one else tackled this:
>
> You're using Partial Functions improperly. That being, if you want to
> combine PartialFunctions, andThen will compose them. However, it
> assumes that each one *completely* matches the space, or throws an error.
>
> If you want to join them "case-wise" so-to-speak you want to use the
> orElse function. When combining receive methods from an actor
> hierarchy, orElse is how you need to do it, unless you want the first
> function to be the only thing that has a chance to match against the input.
>
> - Josh
>
> P.S. - Not sure what variant of Scala you're using, but the code you
> posted is quite... uncompilable for me.
>
> On Wed, Jun 9, 2010 at 5:35 PM, Stefan Kuhn > wrote:
>
> trait Logtor extends Actor ... {
>
> val idFun : PartialFunction[Any, Any]= { case x => x}
>
> abstract override def receive[R](f: PartialFunction[Any, R]): R = {
> // super.receive(f) // <<< no error
> super.receive(idFun andThen f) // <<< error!!!
> //thesis.bsps.sort.WorkerNode@X: caught scala.MatchError:
> //PivotedSlice(2,X)
> }
>
> The error is non-deterministic but reproducible.
> Tests exist which always produced the error.
>
> Switch Line 16 vs 17 to see.
> http://github.com/Stefanqn/Sbt_2.8/blob/master/src/main/scala/thesis/exp...
>
> Testsuite is at:
> Sbt_2.8/
> src/test/scala/thesis/bsps/sort/RegularSamplingScalaActorsTest.scala
>
> It's Scala RC3. The project is build with SBT with managed libs only.
>
> Any ideas what's wrong?
> By the way, the app sorts distributed, with RegularSampling / PSRS.
>
>
> Thanks in advance
> stefan
>
>
>
> ----- stack trace -----
> thesis.bsps.sort.WorkerNode@250d593e: caught scala.MatchError:
> PivotedSlice(0,[I@6f649b44)
> scala.MatchError: PivotedSlice(0,[I@6f649b44)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$3.apply(RegularSamplingScalaActors.scala:126)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$3.apply(RegularSamplingScalaActors.scala:126)
> at scala.PartialFunction$$anon$2.apply(PartialFunction.scala:58)
> at scala.actors.Actor$class.receive(Actor.scala:487)
> at
> thesis.bsps.sort.WorkerNode.thesis$experimental$Logtor$$super$receive(RegularSamplingScalaActors.scala:95)
> at thesis.experimental.Logtor$class.receive(Logtor.scala:17)
> at
> thesis.bsps.sort.WorkerNode.receive(RegularSamplingScalaActors.scala:95)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply$mcV$sp(RegularSamplingScalaActors.scala:103)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply(RegularSamplingScalaActors.scala:103)
> at
> thesis.bsps.sort.WorkerNode$$anonfun$act$2.apply(RegularSamplingScalaActors.scala:103)
> at scala.actors.Reactor$class.seq(Reactor.scala:280)
> at
> thesis.bsps.sort.WorkerNode.seq(RegularSamplingScalaActors.scala:95)
> at scala.actors.Reactor$$anon$3.andThen(Reactor.scala:258)
> at scala.actors.Combinators$class.loop(Combinators.scala:26)
> at
> thesis.bsps.sort.WorkerNode.loop(RegularSamplingScalaActors.scala:95)
> at
> scala.actors.Combinators$$anonfun$loop$1.apply(Combinators.scala:26)
> at
> scala.actors.Combinators$$anonfun$loop$1.apply(Combinators.scala:26)
> at
> scala.actors.Reactor$$anonfun$seq$1$$anonfun$apply$1.apply(Reactor.scala:277)
> at scala.actors.ReactorTask.run(ReactorTask.scala:34)
> at scala.actors.ReactorTask.compute(ReactorTask.scala:66)
> at
> scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:147)
> at
> scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
> at
> scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)
> at
> scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325)
>
>
>
>
>
>
>

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland