def state = 'confused

I think method definitions in Scala can be a bit confusing.

Here’s a REPL session with some comments and questions:

scala> def A() = 'A
A: ()Symbol

scala> def B = () => 'B
B: () => Symbol

scala> def C = 'C
C: Symbol

So far nothing strange, but note the the type of C; is it really a function?

We’ll see later, so let’s move on:

scala> A()
res: Symbol = 'A

scala> B()
res: Symbol = 'B

Note that A and B can be called in the same way, even though B was defined in terms of an anonymous function.

scala> C()
<console>:7: error: C of type Symbol does not take parameters

Well, seems like we’ve discovered that C isn’t really a function and we could have defined it with val instead… Or? No, it’s still a function: the function body wasn’t evaluated until we referred to the function. Look here:

scala> def t = currentTime 
t: Long

scala> t
res: Long = 1296163141271

scala> t
res: Long = 1296163141949

Clever and useful, but not completely obvious.

Back to A, B and C. Let’s try grabbing a function reference Scheme/Haskell/Python style:

scala> A
res: Symbol = 'A

scala> B
res: () => Symbol = <function0>

scala> C
res: Symbol = 'C

B worked fine and C was expected because of what we previously discovered, but what about A? It surprised me that it evaluated to 'A instead of a function that returns 'A. What would the result be if the method took arguments?

scala> def id[T](x: T) = x
id: [T](x: T)T

scala> id
<console>:7: error: missing arguments for method id in object $iw;
follow this method with `_' if you want to treat it as a partially applied function

Different result – yes – but not valid as is. It is noteworthy that it is possible to referr to id like this:

scala> Some(123).map(id)
res: Option[Int] = Some(123)

It seems like the expression is context-sensitive. :/

What I’ve learnt from this that you can’t consider functions and methods as equals in Scala (like in Python); they live in two different worlds and you need to bridge them explicitly sometimes.