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
C()
^
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
id
^
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.