Heavily inspired by Manuel Rotter's HackerNews post: Conways Game of Life in Clojure.You should definitely check that out.In fact, I intersperse his Clojure code with my Scala code, so you can compare & contrast the two.

Scala's green italics, Clojure's plain blue.

Fire up the Scala REPL.

Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_04).Type in expressions to have them evaluated.Type :help for more information.scala>

1. Define a function to create a rectangular world with live cells "X", dead cells " ".

4. Write a higher-order function that takes three arguments: A function to determine the neighbors, a predicate which determines whether a cell shall be given life, and one predicate that determines whether a cell survives to the next generation. It then returns a function which calculates the next generation according to the given rules.

But how does that piece of Scala code work ?!!Okay, this one's quite hard if you've never done this sort of thing before. So lemme dumb this down a bit: A higher-order function is a function that takes a function as input and/or returns a function as output. Most imperative languages either don't provide for higher-order functions, or do so in a convoluted fashion so nobody uses the facility. otoh, the hallmark of a functional language is the ease with which you can create higher-order functions.

Now, the stepper function is a higher order function takes three input functions and returns one output function.1. The first input function must determine the neighbors of a cell, given the cell's x & y locations. The locations are in an Int tuple, and the neighbors would be a list of 8 Int tuples. So its type would be

type nbr_type = (Int,Int)=>List[(Int,Int)]

2. The second input function is a predicate. It must take in a list of neighbor counts, and based on the count, return a boolean if a cell comes alive. For example - Conway says "if a cell has three live neighbors it comes alive, as if by reproduction".Given a neighbor count, the predicate would return true only if the count was equal to 3, by doing a check against the contains() function of List(3)

type birth_type = Int => Boolean

3. The third input function is a predicate. It must take in a list of neighbor counts, and based on the count, return a boolean if a cell survives another generation. For example - Conway says "Any live cell with 2 or 3 live neighbors lives on to the next generation".Given a neighbor count, the predicate would return true only if the count was either 2 or 3, by doing a check against the contains() function of List(2,3)

type survive_type = Int => Boolean

BTW: survive_type is identical to birth_type, so just use one of them, as I've done below.

4. The output function must calculate the next generation given the previous generation. A generation is simply a list of integer tuples. So the mapping is pretty straightforward.

type nextgen_type = List[(Int,Int)] => List[(Int,Int)]

BTW: You can omit nextgen_type because return types are inferred in Scala, and I've done so below.

So, how does the stepper function actually work ? Let's first define a dumb stepper. The dumb stepper simply returns the current generation unchanged as the next generation. The identity function, so to speak.

Well, you give it a list of integer tuples that indicate the cells alive in the current generation ( alive )

((alive:List[(Int,Int)]) =>

The dead cells are the unique neighbors of the alive cells. We first get these neighbors, which is a list of lists, flatten it out & remove the duplicates and filter out the neighbors that happen to be alive.

val dead = alive.map( c=> nbrs(c._1,c._2)).flatten.removeDuplicates.filterNot( x=> alive.contains(x))At this point you have a partition = two sets = the alive set & the dead set.

Given a live cell from the alive set, you find its live neighbors by doing an intersection of its neighbors-set with alive-set.You count its live neighbors by invoking size.You run this count by the survive predicate, and that tells you if this live cell survives another generation.

Given a dead cell from the dead set, you find its live neighbors by doing an intersection of its neighbors-set with alive-set.You count its live neighbors by invoking size.You run this count by the birth predicate, and that tells you if this dead cell is reborn in the next generation.

So you see, you do the same exact thing for both sets in the partition, except for one tiny difference. The alive set is checked against the survive predicate, and the dead cells against the birth predicate.

So start out by bundling each set with its appropriate predicate. List( (alive, survive), (dead, birth) )

5. At this point, we're done! We could define yet another convenience wrapper to iterate over stepper...this last function just helps us to determine the evolution according to Conway's Game of Life by giving it the size of the world, an initial pattern and the number of the generation we want to see.

This sort of thing continues throughout the article. 'nbrs' instead of 'neighbors' proves what? Anyone can write unreadable code in any language.

Krishnan

8/30/2012 10:28:19 am

Sorry, I was simply looking for equivalent Scala code that mimics the functionality in Clojure. Not going for a KLOC comparison. It is simply incidental that I ended up with 10 lines of Scala vs 17 lines of Clojure. In fact if you notice, the stepper function is twice as long in Scala as in Clojure, due to type declarations.
Highly recommend you to rename functions & indent for readability & so forth.

You are going traveling. You have lots of expenses to cover. You need to pay for your air fare, your accommodation, your food, your travel while away, cultural experiences and the list goes on. You want to save money so you decide not to bother with travel insurance.

Clojure has a zen-like quality, it defines few elementary orthogonal concepts which can be combined in powerful ways. where scala is empower the programmer in any possible way, it throws in shortcuts, many of the methods can be done with the minimal amount of code.

Assuming that only cheap, poor quality clothing is available online would be incorrect. There are some online clothing stores that sell their own lines of clothing or that of their suppliers, and even though the clothes are less expensive, they are of good quality and material.

Thanks for the clarification in the blog. I could understand a bit more about Scala and Clojure thanks to you. In fact, could you please suggest me a good book that has got a clear cut definitions and examples of Scala in greater detail?

Conway originally conjectured that no pattern can grow indefinitely i.e., that for any initial configuration with a finite number of living cells, the population cannot grow beyond some finite upper limit. Thanks for sharing.

Write a higher-order function that takes three arguments: A function to determine the neighbors, a predicate which determines whether a cell shall be given life, and one predicate that determines whether a cell survives to the next generation.

Write a upper-arrangement object that borrows trio controversys: A duty to discover the adjoins, a affirm which ascertains whether a dungeon shall be given essence, also united aver that ascertains whether a chamber persists to the adjoining period.