When to use the equals sign in a Scala method declaration?

Solution 1:

I actually disagree pretty strongly with Daniel. I think the non-equal syntax should never be used. If your method is being exposed as an API and you're worried about accidentally returning the wrong type, add an explicit type annotation:

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello!")
    123
  }
}

The non-equal syntax is shorter and might look "cleaner", but I think it just adds the possibility of confusion. I have sometimes forgotten to add an equal sign and believed my method was returning a value when actually it was returning Unit. Because the non-equal and equal-with-inferred-type syntaxes are so visually similar, it's easy to miss this problem.

Even though it costs me a little more work, I prefer the explicit type annotations when they matter (namely, exposed interfaces).

Solution 2:

UPDATE: as of Scala-2.10, using equals sign is preferred. Old answer:

Methods which return Unit should always use the non-equals syntax. This avoids potential mistakes in implementation carrying over into the API. For example, you could have accidentally done something like this:

object HelloWorld {
  def main(args: Array[String]) = {
    println("Hello!")
    123
  }
}

Trivial example of course, but you can see how this might be a problem. Because the last expression does not return Unit, the method itself will have a return type other than Unit. This is exposed in the public API, and might cause other problems down the road. With the non-equals syntax, it doesn't matter what the last expression is, Scala fixes the return type as Unit.

It's also two characters cleaner. :-) I also tend to think that the non-equals syntax makes the code just a little easier to read. It is more obvious that the method in question returns Unit rather than some useful value.

On a related note, there is an analogous syntax for abstract methods:

trait Foo {
  def bar(s: String)
}

The method bar has signature String=>Unit. Scala does this when you omit the type annotation on an abstract member. Once again, this is cleaner, and (I think) easier to read.

Solution 3:

You must use equals sign in call declarations except the definitions returning Unit.

In this latter case, you may forgo the equals sign. This syntax may be deprecated, though, so it's best avoided. Using equals sign and declaring the return type will always work.

Solution 4:

For methods, Scala Style Guide recommends the equals syntax as opposed to procedure syntax

Procedure Syntax

Avoid the procedure syntax, as it tends to be confusing for very little gain in brevity.

// don't do this
def printBar(bar: Baz) {
  println(bar)
}
// write this instead
def printBar(bar: Bar): Unit = {
  println(bar)
}