87

With equals sign:

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

Without equals sign:

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

Both of the above programs execute the same way. In the blog post Things I do not like in Scala I read that when the equals sign are missing, the method will return Unit (same as Java's void), so methods that return a value must use the equals sign. But methods that don't return a value can be written either way.

What is the best practice for using the equals sign in Scala methods that don't return a value?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Esko Luontola
  • 73,184
  • 17
  • 117
  • 128

7 Answers7

111

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).

Jorge Ortiz
  • 4,722
  • 1
  • 21
  • 22
  • 1
    I like this approach, it's more explicit and thus more clear to the reader. – Lukasz Korzybski Oct 30 '12 at 13:50
  • 4
    Apparently that is now the recommended style (http://docs.scala-lang.org/style/declarations.html#procedure_syntax) so I'm changing this to be the accepted answer. – Esko Luontola Jan 31 '14 at 19:38
  • 1
    I agree with that too, I think the syntax without the = should be removed altogether from the language – Ahmed Farghal Feb 05 '14 at 16:12
  • 7
    Martin Odersky in his keynote "Scala with Style" said that it was a historical mistake. He had to add this syntax (without =) so that he can hide "Unit" from Java developers so that they don't get confused. Also he mentioned that it will be removed in the future. – tabdulradi Feb 05 '14 at 16:19
  • 2
    Is there any way to WARN if equals sign was forgotten in method definition? As a compiler option, for example, or in any source analysis tool? – VasiliNovikov Mar 26 '14 at 15:51
  • I _really_ can't see the benefit of this. When I write a method, the first thing I think of after parameter parenthesis is: is this going to return something? If yes, then specify the type followed by '=', else '{'. This new style just means more code for something that doesn't do anything. – krookedking Jul 29 '14 at 13:34
  • This is because `Unit { ... }` is a type refinement, so `def f(): Unit { ... }` declares an abstract method returning `Unit { ... }`. –  Oct 24 '14 at 08:10
42

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.

VasiliNovikov
  • 9,681
  • 4
  • 44
  • 62
Daniel Spiewak
  • 54,515
  • 14
  • 108
  • 120
  • 3
    Not using the equals sign is also the recommendation in the Scala Style Guide: http://davetron5000.github.com/scala-style/types/inference/void_methods.html – Esko Luontola May 22 '10 at 09:15
  • 6
    I wrote that bit, so you should probably keep that in mind when you weigh the reference. :-) – Daniel Spiewak May 22 '10 at 21:34
  • LoL, so I described this little exchange to my girlfriend, except due to my poor enunciation "bit" came out as "bitch". Needless to say, comedy ensued. – Saem Nov 28 '10 at 19:01
  • 10
    ScalaDays 2013, Martin Odersky, [Keynote - Scala with Style chapter 45](http://www.parleys.com/play/51c1994ae4b0d38b54f4621b/chapter45/about): procedure declaration (non-equals syntax) should be avoided. – senia Jul 06 '13 at 12:33
  • 4
    Official style guide does not recommend this anymore: http://docs.scala-lang.org/style/declarations.html#procedure_syntax – sbilstein Nov 20 '13 at 23:39
12

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.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • Books, mailing list, source code. By the way, since that time it became clear that the latter syntax is unlikely to be deprecated, and it is favored by many. – Daniel C. Sobral Jun 24 '13 at 15:35
  • 1
    http://docs.scala-lang.org/style/types.html#function_values Looks like the types style guide indicates using = all the time anyway. – BeepDog Jan 30 '14 at 20:01
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)
}
cmd
  • 11,622
  • 7
  • 51
  • 61
0

One thing : imagine the last statement of a method that should return Unit does not return Unit. Using the non-equal syntax is then very convenient, I hope this will not be deprecated as I see several use case for it

jos
  • 9
  • 1
0

As time as progressed the default style has changed, and this has been mentioned in many of the comments to answers, it is recommended in the official style guide to use the = syntax for function declarations.

BeepDog
  • 5,016
  • 2
  • 24
  • 33
  • 1
    The link you provided only talks about functions, not procedures (i.e. functions which return Unit). – Esko Luontola Jan 31 '14 at 19:35
  • You're right, @EskoLuontola, Sorry about that, I probably copied the wrong link out of one of many tabs I had open, it's been updated. – BeepDog Feb 11 '14 at 16:14
0

for method that dont have a return value, a way to express such methods is leaving out the result type and the equals sign, following the method with a block enclosed in curly braces. In this form, the method looks like a procedure, a method that is executed only for its side effects.

sofiene zaghdoudi
  • 3,108
  • 2
  • 17
  • 11