Omgo's Blog

October 18, 2010

scala simple number guess application using case pattern guards

Filed under: scala — aswin @ 11:15 pm

There are millions of examples out there on all this, but here is a little program that shows the case pattern guards and function literals

class NumGuessCase(guess: Int) {

  def guessNum(read: () => Int, disp: String => Unit): Unit = _guessNum(read, disp)

  private def _guessNum(read: () => Int, disp: String => Unit, times: Int = 0): Unit = {
    disp("Please enter guess :> ")    
    read() match {
      case `guess` => disp("You guessed right in " + (times+1)); 
      case a if a > guess => disp ("You guessed too high");
                _guessNum(read, disp, times+1)
      case a if a < guess => disp ("You guessed too low");
                _guessNum(read, disp, times+1)
    }
  }

}

The guessNum method takes two arguments, read, and disp. Parameter “read” is a function which when invoked should return the user’s guess. “disp” (display) represents a function which is responsible for the output of the messages by the guessNum function. So the client of the guessNum can pass in as arguments a function that accepts user input and another one that displays the messages back to user and in our case we just use system console for this interaction (see the NumGuesCase companion object shown below).

The part I was testing out was the case pattern guards, the second case statement would match only if the pattern guard (“a > guess”) returns true. We could have used a default catch all pattern (“_”) as the last case statement. The first statement uses a variable pattern and is why you have to use the ` (backquote) symbol.

object NumGuesCase extends Application {
  new NumGuessCase(new java.util.Random().nextInt(100)).guessNum(readInt,println)
}

This is how you would use the guessNum method, just pass in a readInt and println method. Scala compiler would capture these methods as Fuction objects and pass it to our guessNum method and since they both Type check with the Function signature it works.

If anyone is trying this out , please be aware of the missing main method bug (pre 2.8.0) as detailed out here

June 25, 2010

scala gotcha

Filed under: scala — aswin @ 3:54 am

I was bitten by this one and it was painful 🙂 . http://daily-scala.blogspot.com/2010/05/return-value-of-block.html

June 7, 2010

scala call-by-name (=>) vs call-by-type

Filed under: scala — aswin @ 9:43 pm

Scala has lot of small surprises and this is one such thing

Given the following

  def byName(a: => Unit) = {
    for (i <- 0 until 10) {println(a)}

  }

  def byValue(a: Unit) = {
    for (i <- 0 until 10) {println(a)}

  }

  var i = 1;

  byValue(i = i + 1)
  println(i);

  byName(i = i + 1)
  println(i)

This would print 2 followed by 12. What is happening here is that in case of byName the evaluation of the arguments happens after the the byName method itself is invoked and the evaluation happens everytime the method parameter “a” is used within the body on the byName method. Since the parameter “a” is refereed in the loop of 10, it executes the statement “i = i +1” 10 times yeielding the result of 12.
In case of byValue (the default invocation mechanism in scala and also in java) the statements in parameter position is evaluated before the actual method call and only the result is passed to the method and hence the evaluation happens only once.
Pretty important difference as this could lead to unintended behavior if not careful. BTW the way create a byName call is having the “=>” between the parameter and the returntype in the argument list “byName(a: => Unit)”

References
http://scala.sygneca.com/faqs/language#what-s-the-difference-between-a-lazy-argument-a-no-arg-function-argument-and-a-lazy-value
http://www.scala-lang.org/sites/default/files/sids/rytz/Mon,%202009-11-09,%2017:29/named-args.pdf (named args and such)

The named arg feature introduced in 2.8 : http://www.scala-lang.org/sites/default/files/sids/rytz/Mon,%202009-11-09,%2017:29/named-args.pdf

Create a free website or blog at WordPress.com.