Liz Douglass

Things that made me go hmmmm…

with 2 comments

Over the last couple of months I’ve been working on a Scala project. There is nothing quite like immersing yourself in a language to increase your knowledge. Along the way I figure that I must have made every possible syntax mistake. This post is about three gotchas – detail of the language has tripped me up.

Method invocation with parentheses

As a general rule, it’s not necessary to use parentheses when invoking Scala methods that have either none or one argument. There are two cases where this does not apply however:

1. Default arguments:
Soon after making the switch over from Scala 2.7.7 to 2.8.0 we made our first attempt at using a default parameter. It went something like this:

object MyObject {
  def something(someArg: String = "Fred"){ println(someArg) }
}

class Foo() {
  MyObject something
}

This results in this error:

error: missing arguments for method something in object MyObject;
follow this method with `_' if you want to treat it as a partially applied function
         MyObject something

As pointed out here “If a method definition includes parentheses, when you call it you must also use parentheses. Presumably this still holds if all the arguments to the method have default values.”

2. Using println:

scala> println 10
<console>:1: error: ';' expected but integer literal found.
       println 10
               ^
scala> println(10)
10

According to Programming In Scala: “Note that (the no parentheses) syntax only works if you explicitly specify the receiver of the method call. You cannot write ‘println 10’, but you can write ‘Console println 10’.”

Case?

In my opinion one of the best things about Scala is the first-order functions that are defined on the TraversibleOnce trait. I’d use a couple of them on any given day. I’ve often needed to perform an operation on each key-value pair in a Scala Map. On more than one occasion I’ve started off writing something like this:

val myMap = Map("hay" -> "stack", "killer" -> "whale")
myMap.filter((key, value) => key == "killer").map((key, value) => value)

Which results in this error:

error: wrong number of parameters; expected = 1

Doing this another way using a for expression gives a better result however:

scala> for((key,value) <- myMap if (key == "killer")) yield(value)
res19: scala.collection.immutable.Iterable[java.lang.String] = List(whale)

Programming In Scala explains that the Scala compiler translates all for expressions into combinations of higher order methods:
“A for expression of the form:
for (x <- expr1 if expr2) yield expr3
is translated to:
for (x expr2)) yield expr3

and: “A for expression of the form:
for((x1, ..., xn) <- expr1) yield expr2
translates to:
expr.map{case (x1,...,xn) => expr2}"

So if I want to use higher order methods as I attempted to do first, I need:

scala> myMap.filter({case(key, value) => key == "killer"}).map({case(key, value) => value})
res29: scala.collection.immutable.Iterable[java.lang.String] = List(whale)

Or the equivalent shorter version:

scala> myMap.filter(_._1 == "killer").map(_._2)
res30: scala.collection.immutable.Iterable[java.lang.String] = List(whale)

Booleans

A java.lang.Boolean does not implicitly convert to a Scala Boolean. You need to convert the java.lang.Boolean into a java boolean type using the booleanValue method in order for the conversion to be possible:

scala> val javaBoolean: java.lang.Boolean = true
javaBoolean: java.lang.Boolean = true

scala> val scalaBoolean: Boolean = javaBoolean
<console>:13: error: type mismatch;
 found   : java.lang.Boolean
 required: scala.Boolean
       val scalaBoolean: Boolean = javaBoolean
                                   ^

scala> val scalaBoolean: Boolean = javaBoolean.booleanValue
scalaBoolean: Boolean = true
Advertisements

Written by lizdouglass

December 15, 2010 at 9:25 am

Posted in Uncategorized

Tagged with

2 Responses

Subscribe to comments with RSS.

  1. Hi Liz,

    I am a grad joining TW in January in Sydney. Wondering how prevalent Scala is within the company, and what the likelihood of working with it.

    Dom (https://github.com/dbousamra)

    dombou70

    August 22, 2012 at 12:02 pm

  2. Hi Dom,
    Great to hear that you’re joining TW. I’ve used two Scala on two projects but they were both in the UK. I don’t believe we’ve had a Scala project as yet in Australia, although I know a few of our clients are interested in it.
    Liz

    lizdouglass

    August 22, 2012 at 10:48 pm


Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: