barbara
barbara

Reputation: 3201

Scala: Why can I pass a quite strange argument to the function?

I have defined method double.

def double(i: Int): Int = i * 2

val p = double {
  print("Hello!");
  5
}

print(p)

As you can see we can pass not just integer argument, but we also can invoke some logic (print). Why can I do that? And how Scala do resolve it? What does really mean {} in Scala?

Upvotes: 1

Views: 75

Answers (3)

elm
elm

Reputation: 20415

As aforementioned, the last expression of an anonymous block is returned; (obviously) nested anonymous blocks works as well,

val p = double {
  val a = 2
  val b = { println("Hello!"); 3 }
  a+b
}
Hello!
p: Int = 10

Note p type conveys the return type declared for double.

Likewise,

val p = double { 2 + { println("Hello!"); 3 } }
Hello!
p: Int = 10

Upvotes: 1

MGolovanov
MGolovanov

Reputation: 65

In this case {} means anonymous block of code. The result of invocation of code block equals to the last block's expression result.

Your code equivalent to this one

val p = double( {
  print("Hello!");
  5
})

Code block evaluation result is a parameter for double. This works because block evaluation result is 5 and have Int type.

Function params evaluation doing before body of function will invoke. First expression of code block is print and therefor print("Hello!"); will be called first. The last expression is 5 and take as function parameter.

val p = double(5)

And then print result of double is 10.

Total result of this code is printing to console

Hello!10

Upvotes: 3

dk14
dk14

Reputation: 22374

Your code is equivalent to:

val p = double({ //`{}` still means a block of code
  print("Hello!") 
  5
})

or even:

def block = { //might be `def block() { ... }`
  print("Hello!")
  5
}

val p = double(block) //calling the block here, it's equivalent to double(block())

So it's just syntactic sugar to help developers to build some handy DSLs, which are looking like native language parts.

Upvotes: 3

Related Questions