Leigh
Leigh

Reputation: 41

Why the function call never gets executed?

I have a function defined like

def counter(x: Int) = {
  var i = x
  () => {
    i = i + 1
    println(i)
  }
}

val count = counter(0)

So count is a function taking no parameter returning Unit. Then the parenthesis could be omitted when calling count. But if I call it by just saying count, i in fact will not be added and nothing happens. In the meantime, a compiler warning will be given like "A pure expression does nothing you may be omitting the parenthesis".

If I call it with parentheses like count(), everything is all right and increased i will be printed.

Why saying count doesn't work? Thank you.

Upvotes: 0

Views: 137

Answers (3)

Sean Vieira
Sean Vieira

Reputation: 159905

A Function0 does not correspond to a parameterless method exactly. That is to say:

val returnOne = () => 1

// approximates
def returnOne() = 1

// rather than 
def returnOne = 1

In fact, once you lift a parameterless method to a Function0 the parameterless method behavior is lost:

// Define a parameterless method
scala> def returnOne = 1
returnOne: Int

// Every time you reference the method it is evaluated
scala> returnOne
res2: Int = 1

// Lift the method to a Function0
scala> returnOne _
res3: () => Int = <function0>

// Now a reference to the lifted method evaluates to the lifted method
scala> res3
res4: () => Int = <function0>

// And you have to invoke it explicitly
scala> res3()
res5: Int = 1

Upvotes: 0

senia
senia

Reputation: 38045

You can't call function without parentheses. In scala you can call method without arguments with no parentheses. Method, but not function.

Actually "call function" means "call method apply of object of type FunctionN" in scala.

So count() means count.apply(). You can call method apply with no parentheses like this: count.apply.

Upvotes: 1

scand1sk
scand1sk

Reputation: 1124

Your counter(x:Int) method actually returns the function () => { ... } you have defined (which returns Unit and generates the compiler warning).

So by calling count with parentheses, you actually execute the function.

If I desugar type inference, you obtain:

def counter(x: Int): () => Unit = {
  var i = x
  () => {
    i = i + 1
    println(i)
  }
}

val count: () => Unit = counter(0)

Upvotes: 0

Related Questions