tags:

views:

145

answers:

4

What exactly is the difference between:

scala> def foo = 5
foo: Int

and

scala> def foo() = 5
foo: ()Int

Seems that in both cases, I end up with a variable foo which I can refer to without parenthesis, always evaluating to 5.

+2  A: 

What does it mean when I use def to define a field in Scala

You can't define a field using def.

Seems that in both cases, I end up with a variable foo which I can refer to without parenthesis, always evaluating to 5.

No, in both cases you end up with a method foo, which you can call without parentheses.

To see that, you can use javap:

// Main.scala
object Main {
  def foo1 = 5
  def foo2() = 5
}


F:\MyProgramming\raw>scalac main.scala

F:\MyProgramming\raw>javap Main
Compiled from "main.scala"
public final class Main extends java.lang.Object{
    public static final int foo2();
    public static final int foo1();
}

However, see http://tommy.chheng.com/index.php/2010/03/when-to-call-methods-with-or-without-parentheses-in-scala/

Alexey Romanov
+12  A: 

You're not defining a variable in either case. You're defining a method. The first method has no parameter lists, the second has one parameter list, which is empty. The first of these should be called like this

val x = foo 

while the second should be called like this

val x = foo()

However, the Scala compiler will let you call methods with one empty parameter list without the parentheses, so either form of call will work for the second method. Methods without parameter lists cannot be called with the parentheses

The preferred Scala style is to define and call no-argument methods which have side-effects with the parentheses. No-argument methods without side-effects should be defined and called without the parentheseses.

If you actually which to define a variable, the syntax is

val foo = 5
Dave Griffith
Actually, Scala will let you elide any number of (trailing) empty parameter lists! Try `def x()()()()()()() = 5`!
Rex Kerr
+4  A: 

Before anything else is said, def does not define a field, it defines a method.

In the second case, you can omit parenthesis because of a specific feature of Scala. There are two differences of interest here: one mechanical, and one of recommended usage.

Beginning with the latter, it is recommended usage to use empty parameter list when there are side effects. One classic example is close(). You'd omit parenthesis if there are no side effects to calling the element.

Now, as a practical difference -- beyond possible weird syntactic mix-ups in corner cases (I'm not saying there are, just conjecturing) -- structural types must follow the correct convention.

For example, Source had a close method without parenthesis, meaning a structural type of def close(): Unit would not accept Source. Likewise, if I define a structural method as def close: Unit, then Java closeable objects will not be accepted.

Daniel
+1  A: 

Additionally to the answers already given I'd like to stress two points:

  • The possibility to define methods without a parameter list is a way to realize the Uniform Access Principle. This allows to hide the difference between fields and methods, which makes later implementation changes easier.

  • You can call a method defined as def foo() = 5 using foo, but you can't call a method defined as def foo = 5 using foo()

Landei