7

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.

5 Answers 5

17

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
Sign up to request clarification or add additional context in comments.

1 Comment

Actually, Scala will let you elide any number of (trailing) empty parameter lists! Try def x()()()()()()() = 5!
7

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.

Comments

4

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/

Comments

4

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

Comments

0

I'm surprised that nobody mentioned anything about the laziness difference. While val is evaluated only once at the time of definition, def is evaluated only when we access it and evaluated every-time we access it. See example below:

scala> def foo = {
     | println("hi")
     | 5
     | }
foo: Int

scala> val onlyOnce = foo
scala> def everyTime = foo

scala> onlyOnce
res0: Int = 5
scala> onlyOnce
res1: Int = 5

scala> everyTime
hi
res2: Int = 5
scala> everyTime
hi
res3: Int = 5

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.