Conway life game implementation with scala I've tried to create optimal in terms of performance and memmory consumption. But also I've tried to make it functional and scala way. I want to get you comment on how to make it more 'scala'stic

object LifeGame extends App {
    trait Matrix extends Iterable[(Int, Int)] {
        def apply(p: (Int, Int)): Boolean
        def update(p: (Int, Int), b: Boolean): Unit
        def newInstance: Matrix;
    }

    class SparseMapMatrix extends Matrix {
        type Point = (Int, Int)

        private var data = Set[(Int, Int)]()

        def apply(p: Point): Boolean = data.contains(p)

        def update(p: Point, b: Boolean) = if (b) data += p else data -= p

        def newInstance = new SparseMapMatrix()

        def iterator = data.iterator

        override def toString() = {
            val sb = new StringBuilder()
            def best(func: (Int, Int) =&gt; Int)(p1: Point, p2: Point) = (func(p1._1, p2._1), func(p1._2, p2._2))
            val minBoundary = ((0, 0) /: iterator)(best(math.min))
            val maxBoundary = ((0, 0) /: iterator)(best(math.max))
            for (i &lt;- minBoundary._1 to maxBoundary._1) {
                sb.append("\n")
                for (j &lt;- minBoundary._2 to maxBoundary._2) {
                    sb.append(if (this((i, j))) "x" else " ")
                }
            }
            sb.append("\nmin=%s, max=%s" format(minBoundary, maxBoundary))
            sb.toString()
        }
    }

    object Engine {
        def apply(input: Matrix): Matrix = {
            val result = input.newInstance
            def block2D(pp: (Int, Int)): Seq[(Int, Int)] =
                for (ii &lt;- block1D(pp._1); jj &lt;- block1D(pp._2)) yield (ii, jj)
            val liveCells = for (p &lt;- input.iterator.flatMap(block2D).toSet[(Int, Int)].par) yield {
                val offsets = block2D(p).filter(_ != p)
                val nn = offsets.map(p =&gt; input(p)).count(_ == true)
                case class State(l: Boolean, n: Int)
                val newValue = State(input(p), nn) match {
                    case State(true, n) if n &lt; 2 =&gt; false
                    case State(true, 2) | State(true, 3) =&gt; true
                    case State(true, n) if n &gt; 3 =&gt; false
                    case State(false, 3) =&gt; true
                    case State(value, _) =&gt; value
                };
                 if(newValue) Some(p) else None
            }
            liveCells.seq.foreach { _ match { case Some(p:Point) =&gt; result(p) = true; case _ =&gt; ;}}
            result
        }
    }

    def block1D(i: Int) = i - 1 to i + 1

}
The main-things I changed:


Matrix is now completely immutable
Code is more self-documenting (extract complex code to methods, etc.)
I deleted the unnecessary inheritance
I don't like apply-methods which are used as contains-methods -> name change
I deleted parentheses in side-effect free methods
Many syntax improvements


The code:

object LifeGame extends App {
  case class Point(x: Int = 0, y: Int = 0)

  object Matrix {
    def empty: Matrix =
      Matrix(Set.empty)
  }

  case class Matrix(private val data: Set[Point]) {

    def contains(p: Point): Boolean =
      data contains p

    def update(p: Point, b: Boolean) =
      if (b) copy(data+p) else copy(data-p)

    def iterator: Iterator[Point] =
      data.iterator

    override def toString = {
      def best(func: (Int, Int) =&gt; Int)(p1: Point, p2: Point) =
        Point(func(p1.x, p2.x), func(p1.y, p2.y))

      val minBoundary = (Point() /: iterator) { best(math.min) }
      val maxBoundary = (Point() /: iterator) { best(math.max) }

      val sb = StringBuilder.newBuilder
      for (i &lt;- minBoundary.x to maxBoundary.x) {
        sb.append("\n")
        for (j &lt;- minBoundary.y to maxBoundary.y) {
          sb.append(if (this contains Point(i, j)) "x" else " ")
        }
      }
      sb.append("\nmin=%s, max=%s" format (minBoundary, maxBoundary))
      sb.toString
    }
  }

  object Engine {

    def newCell: (Boolean, Int) =&gt; Boolean = {
      case (true, 0 | 1) =&gt; false
      case (true, 2 | 3) =&gt; true
      case (true, _) =&gt; false
      case (false, n) =&gt; n == 3
    }

    def apply(input: Matrix): Matrix = {
      def block1D(i: Int) =
        Seq(i-1, i, i+1)

      def block2D(p: Point) =
        for (x &lt;- block1D(p.x); y &lt;- block1D(p.y)) yield Point(x, y)

      def points =
        (input.iterator flatMap block2D).toSet.par

      def calcCell(p: Point) = {
        val neighbours = block2D(p) filter { p != }
        val alive = neighbours map { input contains } count { true == }

        if (newCell(input contains p, alive)) Some(p)
        else None
      }

      val cells = (points map calcCell).seq collect { case Some(p) =&gt; p }
      (Matrix.empty /: cells) { (result, p) =&gt; result(p) = true }
    }
  }
}