Scala object-function balance I am learning Scala, coming from Java background. Here I have written a small prototype proof of concept program that is a part of concept base for a simple upcoming tutorial game. There are two game objects: a Cell and a Breed of cells (a 1d row). The operations are simple. One can create a breed with a number of cells. Each cell can mutate with a custom function chosen randomly from the available set. If the breed mutates, all of it's cells mutate. My question is the one common today - how Scala-ish is my code? How to improve? Coming from OOP, I have witnessed a very strange feeling while writing this code: it feels just like the internals of objects leak out from their ripped bodies just like in a real OOP thriller movie. But everyone suggests breaking the code into functions... so where is the balance?

package main
import scala.util.Random

object Breed extends App{

val rand:Random = new Random

//mutations
def mutF(f:Int =&gt; Int)(v:Int) : Int = {f(v)}

def mutFA(v:Int) : Int = mutF(x =&gt; x)(v)
def mutFB(v:Int) : Int = mutF(x =&gt; x + x)(v)
def mutFC(v:Int) : Int = mutF(x =&gt; x * x)(v)

val mutations : List[Int=&gt;Int] = List(mutFA, mutFB, mutFC)

//constants (sources)
val emptyCellList : List[Cell] = List[Cell]()

//mutations manipulations
def nextMutation(f:Int=&gt;Int) : Int=&gt;Int = {
    val i = mutations.indexOf(f) 
    if(i == mutations.length - 1) mutations(0)
    else mutations(i + 1)
}

def randomMutation : Int=&gt;Int = {
    mutations(rand.nextInt(mutations.length))
}

//---CELL---
class Cell(f:Int=&gt;Int, value:Int) {
    def mutate() = new Cell(nextMutation(f), f(value))
    override def toString = "[" + value + "]"
}

def cellsToString(l:List[Cell]) : String = {
    l match {
        case Nil =&gt; ""
        case y :: ys =&gt; y.toString + cellsToString(ys)
    }

}

//breeder
def createBreed(num:Int) : Breed = {

    def makeCell() : Cell = new Cell(randomMutation, rand.nextInt(10))

    def makeCells(acc:Int, cells:List[Cell]) : List[Cell] = {
        if(acc == 0) cells
        else makeCells(acc - 1, makeCell :: cells)
    }

    new Breed(0, makeCells(num, List[Cell]()))
}

def mutateBreed(gens:Int, breed:Breed) : Breed = {
    def mutate(acc:Int, b:Breed) : Breed = {
        if(acc == 0) b
        else {
            val mutated : Breed = b.mutate();
            println(b.output() + " ---&gt; " + mutated.output())
            mutate(acc - 1, mutated)
        }
    }
    mutate(gens, breed)
}

//---BREED---
class Breed(generation:Int, cells:List[Cell]) {

    def mutateCells() : List[Cell] = {
        def f(l:List[Cell]) : List[Cell] = {
            l match {
                case Nil =&gt; Nil
                case x :: xs =&gt; x.mutate() :: f(xs)
            }
        }
        println("BREED: size=" + cells.length)
        f(cells)
    }

    def mutate() : Breed = new Breed(generation + 1, mutateCells)

    def output() : String = {
        "BREED: [" + generation + "] = " + cellsToString(cells)
    }
}


// /\/\/\/\/test/\/\/\/\
def test() {
    val breed = createBreed(10)
    mutateBreed(10, breed)
}

test
}
Some improvements:


Try to minimize all mutable state and side effecting methods to single places. Don't divide them through the whole program.
Scala is object oriented. Therefore use methods of the objects you want to work with instead of global functions.
use methods with an empty parameter list only if these methods has side effects.
search the API for methods you can work with.


That's what I came up with:

object Game {

  import util.Random

  val rand: Random = new Random
  val mutations: Seq[Int =&gt; Int] = Seq(x =&gt; x, x =&gt; x + x, x =&gt; x * x)

  case class Cell(f: Int =&gt; Int, value: Int) {
    def mutate = {
      def nextMutation: Int =&gt; Int =
        mutations(((mutations indexOf f) + 1) % mutations.size)
      Cell(nextMutation, f(value))
    }

    override def toString = "["+value+"]"
  }

  case class Breed(generation: Int, cells: Seq[Cell]) {
    def mutate: Breed =
      Breed(generation + 1, cells map { _.mutate })

    override def toString: String =
      "BREED: ["+generation+"] = "+cells.mkString
  }

  def makeCells(num: Int) = {
    def randomMutation =
      mutations(rand nextInt mutations.size)

    def makeCell =
      Cell(randomMutation, (rand nextInt 10))

    (Seq fill num) { makeCell }
  }

  def test() {
    val firstBreed = Breed(0, makeCells(10))
    val breeds = ((1 to 10).iterator scanLeft firstBreed) {
      (b, _) =&gt; b.mutate
    }
    printBreeds(breeds)
  }

  def printBreeds(breeds: Iterator[Breed]) {
    (breeds sliding 2) foreach {
      case Seq(b, mutated) =&gt;
        println("BREED: size="+b.cells.size)
        println(b+" ---&gt; "+mutated)
    }
  }

}