Can someone explain the following to me:
scala> def squared(x: Int) = x * x
squared: (x: Int)Int
scala> val sq : (Int) => Int = squared
sq: Int => Int = <function1>
scala> sq.getClass
res111: Class[_ <: Int => Int] = class $anonfun$1
I understand this so far, squared is a function while sq is a function pointer.
But then I do this:
scala> squared.getClass
<console>:13: error: missing arguments for method squared;
follow this method with `_' if you want to treat it as a partially applied function
squared.getClass
^
Why can't I invoke getClass on squared ? After all, aren't functions 1st class objects ? Why do I need to do this for it to work ?
scala> squared(7).getClass
res113: Class[Int] = int
And I also get the same result for
scala> sq(5).getClass
res115: Class[Int] = int
Come to think of it, why do
scala>squared(5)
and
scala> sq(5)
produce the same result, even though one is a function, and the other a function pointer without needing to use a different syntax ?
Something akin to *sq(5)
may have been clearer, no ?
The concept of a pointer isn't really relevant here, or in Scala (or the JVM) more generally. The difference between squared
and sq
is that squared
is a method, and sq
is a function.
Scala is (primarily) a language designed to be compiled to JVM bytecode. The JVM doesn't have first class functions, but it does have methods, which are associated either with an instance of a class (instance methods) or simply with the class itself (static methods). Methods in this sense are a fundamentally different kind of thing than objects to the JVM—they can't be passed as arguments to other methods, etc.
Because Scala is a functional language and functional languages are built on the idea of higher-order functions and first class functions more generally, the Scala language designers needed to be able to encode functions in a way that would work on the JVM. This is done via a Function1
class, and when you write something like this:
val sq: (Int) => Int = x => x * x
You are using Scala's syntactic sugar for creating instances of the Function1
class. These things are functions encoded as JVM objects, so they can be passed around and treated as first class things in the language.
Scala doesn't abandon the idea of methods, though. For reasons related in part to Scala's functional-OOP hybridity and in part to issues of performance, most Scala programs make extensive use of def
definitions, which define methods, not "functions" in the sense of Function1
. Scala provides a special conversion process (called eta expansion) by which methods can be treated as functions in many situations (including the right-hand side of your sq
definition here).
If this all seems confusing, believe me, it is. You get used to it after a while, though (just get the idea of pointers out of your head as quickly as possible).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With