Scala pattern matching in parallel program

I am new to Scala and I want to write some multi-threaded code with pattern matching, and I was wondering if I can consider the pattern matching code as atomic.

For instance:

abstract class MyPoint
case class OneDim(x : Int) extends MyPoint
case class TwoDim(x : Int, y : Int) extends MyPoint

var global_point : MyPoint = new OneDim(7)

spawn {
    Thread.sleep(scala.util.Random.nextInt(100))
    global_point = new TwoDim(3, 9)
}
Thread.sleep(scala.util.Random.nextInt(100))

match global_point {
    case TwoDim(_, _) => println("Two Dim")
    case OneDim(_) => println("One Dim")
}

Is it possible that the execution would look like this:

  • The main thread reaches the match global_point code, detects that * global_point * is not of the TwoDim type and pauses (returns to the scheduler).
  • The initialized stream changes * global_point * to type TwoDim
  • The main thread returns, detects that * global_point * is not of the OneDim type, considers that there is no match with * global_point *, and throws a NoMatch exception.

Scala? , ? , ? ( )?

+5
3

, , , - , . , , .

script scala -print:

var m: Option[String] = _

m match {
  case Some(s) => "Some: " + s
  case None => "None"
}

desugared, ( ):

final class Main$$anon$1 extends java.lang.Object {
  private[this] var m: Option = _;

  private <accessor> def m(): Option = Main$$anon$1.this.m;

  def this(): anonymous class Main$$anon$1 = {
    <synthetic> val temp1: Option = Main$$anon$1.this.m();

    if (temp1.$isInstanceOf[Some]()) {
      "Some: ".+(temp1.$asInstanceOf[Some]().x())
    else if (scala.this.None.==(temp1))
      "None"
    else
      throw new MatchError(temp1)
  }
}

, , m, temp1, , m , , - m . , ( global_point TwoDim ) .

, , , ! script:

case class X(var f: Int, var x: X)

var x = new X(-1, new X(1, null))

x match {
  case X(f, ix) if f >  0 || ix.f > 0  => "gt0"
  case X(f, ix) if f <= 0 || ix.f <= 0 => "lte0"
}

:

private[this] var x: anonymous class Main$$anon$1$X = _;

private <accessor> def x(): anonymous class Main$$anon$1$X = Main$$anon$1.this.x;

final <synthetic> private[this] def gd2$1(x$1: Int, x$2: anonymous class Main$$anon$1$X): Boolean = x$1.>(0).||(x$2.f().>(0));

final <synthetic> private[this] def gd3$1(x$1: Int, x$2: anonymous class Main$$anon$1$X): Boolean = x$1.<=(0).||(x$2.f().<=(0));

def this(): anonymous class Main$$anon$1 = {
  <synthetic> val temp6: anonymous class Main$$anon$1$X = Main$$anon$1.this.x();

  if (temp6.ne(null)) {
    <synthetic> val temp7: Int = temp6.f();
    <synthetic> val temp8: anonymous class Main$$anon$1$X = temp6.x();

    if (Main$$anon$1.this.gd2$1(temp7, temp8))
      "gt0"
    else if (Main$$anon$1.this.gd3$1(temp7, temp8))
      "lte0"
    else
      throw new MatchError(temp6)
  } else
    throw new MatchError(temp6)
}

x, , - x.f ( f) x.x ( ix), ix.f. , , , , , , . , - .

+4

, , , . , . , , , , , . TwoDim OneDim , . , , .

+1

Scala Actor s. Actor s , . , scalas Actor, .

import scala.actors.Actor
import scala.actors.Actor._

abstract class MyPoint
case class OneDim(x: Int) extends MyPoint
case class TwoDim(x: Int, y: Int) extends MyPoint

case object Next
case object End

class OneDimSlave extends Actor {

  def act() {
    println("Starting OneDimSlave")
  loop {
        receive {
          case End => println("Stoping OneDimSlave"); exit()
          case Next => sender ! OneDim(scala.util.Random.nextInt(100))
        }
      }
}

}

class TwoDimSlave extends Actor {

  def act() {
    println("Starting TwoDimSlave")
  loop {
    receive {
      case End => println("Stopping TwoDimSlave"); exit()
      case Next => sender ! TwoDim(scala.util.Random.nextInt(100),scala.util.Random.nextInt(100))
    }
  }
}

}

class Master extends Actor {

  val oneDimSlave = new OneDimSlave
  val twoDimSlave = new TwoDimSlave

  oneDimSlave.start
  twoDimSlave.start

  def act {
    println("Starting Master")
for (_ <- 0 to 9) { oneDimSlave ! Next; twoDimSlave ! Next }
var count = 0
loop {
  if (count >= 20) { oneDimSlave ! End; twoDimSlave ! End; println("Stopping Master"); exit() }
  receive {
    case _ :OneDim => count += 1; println(count + ". One Dim")
    case _: TwoDim => count += 1; println(count + ". Two Dim")
  }
}
  }

}

object Main extends App {
  val master = new Master
  master.start
}

. Actor s, case. , . , MyPoint, . , , . , , . 10 Next . . , End . :

Starting TwoDimSlave
Starting OneDimSlave
Starting Master
1. One Dim
2. Two Dim
3. Two Dim
4. Two Dim
5. Two Dim
6. Two Dim
7. Two Dim
8. Two Dim
9. Two Dim
10. Two Dim
11. Two Dim
12. One Dim
13. One Dim
14. One Dim
15. One Dim
16. One Dim
17. One Dim
18. One Dim
19. One Dim
20. One Dim
Stopping Master
Stopping OneDimSlave
Stopping TwoDimSlave
+1

All Articles