Scala has an abbreviation for code that does not return any interesting value: omit the = sign. In Java, this will return void , i.e. Nothing at all; but in Scala, it is actually () , the only member of the type called Unit . In any case, this is one and the same thing: nothing or a meaningless placeholder.
The reason you need a meaningless placeholder is because when you write general code, you no longer have to handle cases of anything and nothing else.
Anyway:
def f(): Unit = println("Hi")
is a function that explicitly returns only content without content () (which println also returns). And shorthand
def f() { println("Hi") }
Now there is one dastardly addition that Scala has, like many C-type languages, you can just throw the return value from what you are doing. And when you throw it away, all that's left is () . Scala will warn you about closure2 that you are doing something suspicious:
<console>:16: warning: a pure expression does nothing in statement position you may be omitting necessary parentheses foo ^ defined module A
but still allow you to do it (as historically expected to work).
So, we summarize:
def f {}
is a method that returns only content without content () . If you write it completely, the syntax will be
def f: Unit = {}
and when you try to return a value of the wrong type, instead of complaining, it throws the value and gives you the type Unit , but usually gives a warning:
def f: Unit = 5 def f { 5 }
(Please note that opinion is mainly related to short forms these days (these days it is 2.10-stable), largely because in the absence of a clear explanation of the difference, new users often skip = without realizing it, and then wonder why doesnβt it work. So, in the future (2.11 or 2.12 for obsolescence?) the form def f {} may not work.)
If you really want to get the return value - because, for example, you want to return your O object (which you can do directly without first assigning foo , by the way), make sure you include = :
def f = { object O { def g = 5 }; O } scala> fg res0: Int = 5
(Hint: the compiler will complain about you using structural types here. Better with trait HasG { def g: Int } and then object O extends HasG ; otherwise, Scala actually uses reflection to call fg for some that I never could follow.)