Of Scala Functions and Methods

Of Scala Functions and Methods

“What is the difference between a function and a method?” I have been doing Java for so long that I have to paused to think for a moment to answer. Java has no functions, at least before version 8. As far as Scala goes, you can define function using either ways,

scala> def plusOne(i: Int) = i + 1
plusOne: (i: Int)Int

scala> val plusOne = (i: Int) => i + 1
plusOne: Int => Int = <function1>

Or variation of definitions using def and val.

What got me to write this article was not the original question I was asked. It was clearly explained in Programming in Scala Second Edition. Martin Odersky – Lex Spoon – Bill Venners

function A function can be invoked with a list of arguments to produce a result. A function has a parameter list, a body, and a result type. Functions that are members of a class, trait, or singleton object are called methods. Functions defined inside other functions are called local functions. Functions with the result type of Unit are called procedures. Anonymous functions in source code are called function literals. At run time, function literals are instantiated into objects called function values.

I wrote this article to remind myself why functions cannot be overloaded while methods can. For example,

scala> object PlusOneUtils {
         def plusOne(i: Double) = i + 1
         def plusOne(i: Int) = i + 1
       }
defined object PlusOneUtils

scala> PlusOneUtils.plusOne(1)
res2: Int = 2

scala> PlusOneUtils.plusOne(1.0)
res3: Double = 2.0

And,

scala> object SumUtils {
         val sum = (a:Double, b:Double) => a + b
         val sum = (c:Int, d:Int) => c + d
       }
<console>:13: error: sum is already defined as value sum
     val sum = (c:Int, d:Int) => c + d

Methods (defined with def) can be converted to functions,

scala> val p1 = PlusOneUtil.plusOne _
p1: Int => Int = <function1>

But it cannot be overloaded,

scala> val p1:Double = PlusOneUtil.plusOne _ 
<console>:11: error: type mismatch;
 found   : Int => Int
 required: Double
       val p1:Double = plusOne _

While a standalone function will show its type when executed without its parameters,

scala> val p2 = (a:Int, b:Int) => a+b
p2: (Int, Int) => Int = <function2>

scala> p2
res14: (Int, Int) => Int = <function2>

An error would be thrown for function define with def ,

scala> val p1 = PlusOneUtil.plusOne
<console>:11: error: missing arguments for method plusOne in object PlusOne; follow this method with `_' if you want to treat it as a partially applied function
       val p1 = plusOne
                ^

A Curious Case of Method Overloading

There is a curious case resulted in overloading methods of same parameter after type erasure. Usually, scalac, will complaint and terminate the compilation. However, if the return type is different for the methods, scalac will compile and there is no exception thrown during execution. For example,

object Overload{
  def foo(xs : String*) = "foo";
  def foo(xs : Int*) = 3;  // returns an Int type
}

compiles but this would fail the compilation,

object Overload{
  def foo(xs : String*) = "foo";
  def foo(xs : Int*) = "bar";  // returns String type
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s