1

Possible Duplicate:
Difference between method and function in Scala
Two ways of defining functions in Scala. What is the difference?

There are 2 ways to define a function.

scala> def a : (Int, Int) => Int = {(s:Int, t:Int) => s + t}
a: (Int, Int) => Int

scala> a
res15: (Int, Int) => Int = <function2>

scala> def b(s:Int, t:Int) : Int = s+t
b: (s: Int, t: Int)Int

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

scala> b(3,4)
res17: Int = 7

scala> a(3,4)
res18: Int = 7

Is there any difference in how I define functions a and b? Why do I have missing arguments error with b?

Community
  • 1
  • 1
thlim
  • 2,908
  • 3
  • 34
  • 57
  • Question begins with "There are two ways of defining a function". Duplicate (one of them) begins with "Two ways of definitions functions". This isn't a mailing list, it's a database of questions and answer. Use it! – Daniel C. Sobral Mar 27 '12 at 17:47
  • @DanielC.Sobral is right. I wish I had checked before starting to write my answer, but there are in fact other questions that cover the same ground as this one. – Paolo Falabella Mar 27 '12 at 17:58

2 Answers2

6

b is not a function, but a method. You can however turn b into a function by adding the _ as the compiler mentions. val f = b _. But you should only do this, if you want to pass a method of an object to a method/function that takes a function as parameter. If you just want to define a function go the normal way.

But to answer your question, there is another way:

val f = new Function2[Int,Int,Int] {
  def apply(x: Int, y: Int) = x + y
}
drexin
  • 24,225
  • 4
  • 67
  • 81
2

Object Oriented languages (e.g. java) typically have classes and classes have methods, while functions are not "first-class citizens", meaning you can't assign a function directly to a variable or put a few functions in a list or send them as arguments to other functions. If you want to send a function around in java, you have to create a class with a method and send the class around. For instance, if you want to have a function that calculates the double of its input, you have to put it in a class, like this:

class Doubler 
{
  public int apply(int a)
  {
    return a * 2;
  }
}

In functional programming languages, like Haskell, functions are "first-class", and you can store them in variables and send them around.

doubleIt :: Integer -> Integer
doubleIt x =  2 * x

As a beautiful combination of functional and object oriented, scala has both methods and functions.

// a function like in haskell
val doubleIt = (x:Int) => x * 2 

// a method in an object like in java
object Doubler {
    def apply(x:Int) = x * 2
}

In scala def always defines a method. Note that the REPL wraps everything you write in an object with a main (in order to be able to compile and execute it on the fly), but writing a def something not wrapped in a class/object/trait in a program would not compile.

Scala also has a few more perks to offer, to decrease the disconnect between object and first-class functions.

For one thing, the "apply" method over there in the Doubler object definition in scala is sort of magic. Given the definition above, you can write Doubler(2) and scala's compiler will transform this into Doubler.apply(2) and happily return 4. So you can sort of use objects as functions.

But also, you can (by putting a _ sign after the call to a method) transform the method into a real function and (say) assign it to a val.

scala> val d = Doubler.apply _
d: Int => Int = <function1>

scala> d(2)
res1: Int = 4

On the other hand, the way scala makes a function like val doubleIt = (x:Int) => x * 2 into a first class "thing" is by turning it into something like this behind your back.

object Doubler extends Function[Int, Int] {
  def apply(x: Int) = x*2
} 

val doubleIt = Doubler

So, yeah... a function is actually still a class with a method, more or less like in java. Except that scala does it for you and gives you a lot of syntactic sugar to use that generated class as you would use an actual function.

To make things even more interesting, since functions are first-class, one of the things you can do with them in scala is use them as return values from other functions or methods. So when you wrote def a : (Int, Int) => Int = {(s:Int, t:Int) => s + t} you actually defined a method, called a that returns a function. It may be confusing at first (and at second, and at third....) but around the fourth time around it will probably start looking beautiful. At least that's what it did for me.

Paolo Falabella
  • 24,914
  • 3
  • 72
  • 86