The loop method is defined in the Actor object:
private[actors] trait Body[a] { def andThen[b](other: => b): Unit } implicit def mkBody[a](body: => a) = new Body[a] { def andThen[b](other: => b): Unit = self.seq(body, other) } /** * Causes <code>self</code> to repeatedly execute * <code>body</code>. * * @param body the code block to be executed */ def loop(body: => Unit): Unit = body andThen loop(body)
This is confusing, but it happens that the block that comes after the loop (the thing between { and } ) is passed to the seq method as the first argument, and a new loop with this block as the second argument.
As for the seq method, in the Actor we find:
private def seq[a, b](first: => a, next: => b): Unit = { val s = Actor.self val killNext = s.kill s.kill = () => { s.kill = killNext // to avoid stack overflow: // instead of directly executing `next`, // schedule as continuation scheduleActor({ case _ => next }, 1) throw new SuspendActorException } first throw new KillActorException }
So, a new loop is planned for the next action after the kill, then the block is executed, and then an exception of type KillActorException is thrown, which will cause the loop to repeat.
So, the while executes much faster than the loop , because it does not exclude any exceptions, does not execute scheduling, etc. On the other hand, the scheduler gets the opportunity to schedule something else between two loop executions.
Daniel C. Sobral
source share