Monday, August 17, 2009

Return values

As with most functional languages, most control structures ( if, for, try ) return values. The common java idiom:
  1. String name=null;
  2. if( xxx ) name="yyy";
  3. else name="zzz";

can be replaced by
  1. val name = if( xxx ) "yyy"; else"zzz";

The benefit (other than less boiler plate code) is that name can now be a val instead of a var.

Another other point about returns: The return keyword is not required when returning a value from methods or control structures. The last value is always the return value. This is why you will get an error if the last line in a method or control structure is an assignment.

Examples:
  1. scala>val name = if( 1==2 ) "Jesse"else"Mauricio"
  2. name: java.lang.String = Mauricio
  3. scala> println(name)
  4. Mauricio
  5. scala>val collection = for( i <- 1 to 100; if(i%20 == 3) ) yield i
  6. collection: Seq.Projection[Int] = RangeFM(3, 23, 43, 63, 83)
  7. scala> collection.foreach( i => print( i +" ") )
  8. 3 23 43 63 83
  9. scala>val someObj:AnyRef = "Hello"
  10. someObj: AnyRef = Hello
  11. scala>val choice = someObj match {
  12.      | case _:java.io.File => "File"
  13.      | case _:String => "String"
  14.      | case _ => "Dunno"
  15.      | }
  16. choice: java.lang.String = String
  17. scala>val result = try {
  18.      | "two".toInt
  19.      | }catch{
  20.      | case e:NumberFormatException => -1
  21.      | case _ => 0
  22.      | }
  23. result: Int = -1
  24. scala>var i=0
  25. i: Int = 0
  26. // while and do-while do not have return values
  27. scala>while( i<4 ){
  28.      | "22"
  29.      | i += 2
  30.      | }
  31. scala> println( if(i>0) "great"else"less" )
  32. great
  33. // code blocks return the last statement
  34. scala>val m = {
  35.      | val x = 1
  36.      | x + 2
  37.      | }
  38. m: Int = 3

3 comments:

  1. Hi Jesse,

    thanks for posting this wonderful notes on scala.

    I got stuck on this stuff
    collection.foreach( i => print( i +" ") )

    Tried to use "_" in the above call
    collection.foreach(print( _ +" "))

    but getting an error. Trying to understand why this happens. Any insight would be appreciated

    Thanks in advance

    ReplyDelete
  2. I do not know the details but essentially what is happening is that there are 2 functions being created:

    _ + " "
    and
    print _

    In the function: collection.foreach(print( _ +" "))

    The _ refers to the top level function but from a compiler point of view it is not so clear what the _ is standing in for.

    From what I understand the error is one of technical restrictions based on how complicated it is to make the compiler and type inferencer figure out what types are required and so on.

    As a rule of thumb that I go by is that the _ placeholder should only be used where there is no ambiguity of what it applies to.

    So in order to pass the value "down" to the inner function you need to assign the value to an explicit value.

    Hope that makes some sense :P

    ReplyDelete
  3. Jesse, thanks for the clarification, something similar explained over here too.. http://bit.ly/8Hcgh2

    ReplyDelete