By Anantha Kumaran


2010-03-27 12:06:16 8 Comments

I read Scala Functions (part of Another tour of Scala). In that post he stated:

Methods and functions are not the same thing

But he didn't explain anything about it. What was he trying to say?

7 comments

@Valy Dia 2019-04-24 17:37:56

Here is a great post by Rob Norris which explains the difference, here is a TL;DR

Methods in Scala are not values, but functions are. You can construct a function that delegates to a method via η-expansion (triggered by the trailing underscore thingy).

with the following definition:

a method is something defined with def and a value is something you can assign to a val

In a nutshell (extract from the blog):

When we define a method we see that we cannot assign it to a val.

scala> def add1(n: Int): Int = n + 1
add1: (n: Int)Int

scala> val f = add1
<console>:8: error: missing arguments for method add1;
follow this method with `_' if you want to treat it as a partially applied function
       val f = add1

Note also the type of add1, which doesn’t look normal; you can’t declare a variable of type (n: Int)Int. Methods are not values.

However, by adding the η-expansion postfix operator (η is pronounced “eta”), we can turn the method into a function value. Note the type of f.

scala> val f = add1 _
f: Int => Int = <function1>

scala> f(3)
res0: Int = 4

The effect of _ is to perform the equivalent of the following: we construct a Function1 instance that delegates to our method.

scala> val g = new Function1[Int, Int] { def apply(n: Int): Int = add1(n) }
g: Int => Int = <function1>

scala> g(3)
res18: Int = 4

@Mehran 2018-02-23 14:38:27

There is a nice article here from which most of my descriptions are taken. Just a short comparison of Functions and Methods regarding my understanding. Hope it helps:

Functions: They are basically an object. More precisely, functions are objects with an apply method; Therefore, they are a little bit slower than methods because of their overhead. It is similar to static methods in the sense that they are independent of an object to be invoked. A simple example of a function is just like bellow:

val f1 = (x: Int) => x + x
f1(2)  // 4

The line above is nothing except assigning one object to another like object1 = object2. Actually the object2 in our example is an anonymous function and the left side gets the type of an object because of that. Therefore, now f1 is an object(Function). The anonymous function is actually an instance of Function1[Int, Int] that means a function with 1 parameter of type Int and return value of type Int. Calling f1 without the arguments will give us the signature of the anonymous function (Int => Int = )

Methods: They are not objects but assigned to an instance of a class,i.e., an object. Exactly the same as method in java or member functions in c++ (as Raffi Khatchadourian pointed out in a comment to this question) and etc. A simple example of a method is just like bellow:

def m1(x: Int) = x + x
m1(2)  // 4

The line above is not a simple value assignment but a definition of a method. When you invoke this method with the value 2 like the second line, the x is substituted with 2 and the result will be calculated and you get 4 as an output. Here you will get an error if just simply write m1 because it is method and need the input value. By using _ you can assign a method to a function like bellow:

val f2 = m1 _  // Int => Int = <function1>

@K. M 2018-08-16 18:30:01

What does it mean to "assign a method to a function"? Does it just mean that you now have an object that behaves the same way the method did?

@anish 2013-11-01 04:29:12

Let Say you have a List

scala> val x =List.range(10,20)
x: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19)

Define a Method

scala> def m1(i:Int)=i+2
m1: (i: Int)Int

Define a Function

scala> (i:Int)=>i+2
res0: Int => Int = <function1>

scala> x.map((x)=>x+2)
res2: List[Int] = List(12, 13, 14, 15, 16, 17, 18, 19, 20, 21)

Method Accepting Argument

scala> m1(2)
res3: Int = 4

Defining Function with val

scala> val p =(i:Int)=>i+2
p: Int => Int = <function1>

Argument to function is Optional

 scala> p(2)
    res4: Int = 4

scala> p
res5: Int => Int = <function1>

Argument to Method is Mandatory

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

Check the following Tutorial that explains passing other differences with examples like other example of diff with Method Vs Function, Using function as Variables, creating function that returned function

@jamlhet 2014-07-01 20:27:36

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.

Programming in Scala Second Edition. Martin Odersky - Lex Spoon - Bill Venners

@JosiahYoder-deactive except.. 2015-08-19 14:29:19

A function can belong to a class as a def or as a val/var. Only the def's are methods.

@Daniel C. Sobral 2010-03-27 16:27:18

Jim has got this pretty much covered in his blog post, but I'm posting a briefing here for reference.

First, let's see what the Scala Specification tell us. Chapter 3 (types) tell us about Function Types (3.2.9) and Method Types (3.3.1). Chapter 4 (basic declarations) speaks of Value Declaration and Definitions (4.1), Variable Declaration and Definitions (4.2) and Functions Declarations and Definitions (4.6). Chapter 6 (expressions) speaks of Anonymous Functions (6.23) and Method Values (6.7). Curiously, function values is spoken of one time on 3.2.9, and no where else.

A Function Type is (roughly) a type of the form (T1, ..., Tn) => U, which is a shorthand for the trait FunctionN in the standard library. Anonymous Functions and Method Values have function types, and function types can be used as part of value, variable and function declarations and definitions. In fact, it can be part of a method type.

A Method Type is a non-value type. That means there is no value - no object, no instance - with a method type. As mentioned above, a Method Value actually has a Function Type. A method type is a def declaration - everything about a def except its body.

Value Declarations and Definitions and Variable Declarations and Definitions are val and var declarations, including both type and value - which can be, respectively, Function Type and Anonymous Functions or Method Values. Note that, on the JVM, these (method values) are implemented with what Java calls "methods".

A Function Declaration is a def declaration, including type and body. The type part is the Method Type, and the body is an expression or a block. This is also implemented on the JVM with what Java calls "methods".

Finally, an Anonymous Function is an instance of a Function Type (ie, an instance of the trait FunctionN), and a Method Value is the same thing! The distinction is that a Method Value is created from methods, either by postfixing an underscore (m _ is a method value corresponding to the "function declaration" (def) m), or by a process called eta-expansion, which is like an automatic cast from method to function.

That is what the specs say, so let me put this up-front: we do not use that terminology! It leads to too much confusion between so-called "function declaration", which is a part of the program (chapter 4 -- basic declarations) and "anonymous function", which is an expression, and "function type", which is, well a type -- a trait.

The terminology below, and used by experienced Scala programmers, makes one change from the terminology of the specification: instead of saying function declaration, we say method. Or even method declaration. Furthermore, we note that value declarations and variable declarations are also methods for practical purposes.

So, given the above change in terminology, here's a practical explanation of the distinction.

A function is an object that includes one of the FunctionX traits, such as Function0, Function1, Function2, etc. It might be including PartialFunction as well, which actually extends Function1.

Let's see the type signature for one of these traits:

trait Function2[-T1, -T2, +R] extends AnyRef

This trait has one abstract method (it has a few concrete methods as well):

def apply(v1: T1, v2: T2): R

And that tell us all that there is to know about it. A function has an apply method which receives N parameters of types T1, T2, ..., TN, and returns something of type R. It is contra-variant on the parameters it receives, and co-variant on the result.

That variance means that a Function1[Seq[T], String] is a subtype of Function1[List[T], AnyRef]. Being a subtype means it can be used in place of it. One can easily see that if I'm going to call f(List(1, 2, 3)) and expect an AnyRef back, either of the two types above would work.

Now, what is the similarity of a method and a function? Well, if f is a function and m is a method local to the scope, then both can be called like this:

val o1 = f(List(1, 2, 3))
val o2 = m(List(1, 2, 3))

These calls are actually different, because the first one is just a syntactic sugar. Scala expands it to:

val o1 = f.apply(List(1, 2, 3))

Which, of course, is a method call on object f. Functions also have other syntactic sugars to its advantage: function literals (two of them, actually) and (T1, T2) => R type signatures. For example:

val f = (l: List[Int]) => l mkString ""
val g: (AnyVal) => String = {
  case i: Int => "Int"
  case d: Double => "Double"
  case o => "Other"
}

Another similarity between a method and a function is that the former can be easily converted into the latter:

val f = m _

Scala will expand that, assuming m type is (List[Int])AnyRef into (Scala 2.7):

val f = new AnyRef with Function1[List[Int], AnyRef] {
  def apply(x$1: List[Int]) = this.m(x$1)
}

On Scala 2.8, it actually uses an AbstractFunction1 class to reduce class sizes.

Notice that one can't convert the other way around -- from a function to a method.

Methods, however, have one big advantage (well, two -- they can be slightly faster): they can receive type parameters. For instance, while f above can necessarily specify the type of List it receives (List[Int] in the example), m can parameterize it:

def m[T](l: List[T]): String = l mkString ""

I think this pretty much covers everything, but I'll be happy to complement this with answers to any questions that may remain.

@Seth Tisue 2010-05-20 22:37:07

This explanation is very clear. Well done. Unfortunately both the Odersky/Venners/Spoon book and the Scala spec use the words "function" and "method" somewhat interchangeably. (They are likeliest to say "function" where "method" would be clearer, but sometimes it happens the other way too, for example, section 6.7 of the spec, which covers converting methods to functions, is named "Method Values". Ugh.) I think that loose use of these words has led to a lot of confusion when people try to learn the language.

@Daniel C. Sobral 2010-05-20 23:28:34

@Seth I know, I know -- PinS was the book that taught me Scala. I learned better the hard way, ie, paulp set me straight.

@Holger Peine 2013-01-23 15:13:47

Great explanation! I have one thing to add: When you quote the expansion of val f = m by the compiler as val f = new AnyRef with Function1[List[Int], AnyRef] { def apply(x$1: List[Int]) = this.m(x$1) } you should point out that the this inside the apply method does not refer to the AnyRef object, but to the object in whose method the val f = m _ is evaluated (the outer this, so to say), since this is among the values that are captured by the closure (like e.g. return as pointed out below).

@tldr 2013-06-18 21:29:19

@DanielC.Sobral, what is the PinS book you mentioned? I'm also interested in learning Scala, and haven't found a book with that name,

@Daniel C. Sobral 2013-06-18 22:59:35

@tldr Programming in Scala, by Odersky et all. It's the common abbreviation for it (they did tell me they didn't quite like PiS for some reason! :)

@acjay 2014-07-16 17:56:04

@DanielC.Sobral I'm not sure PinS is all that much better when pronounced quickly!

@MaxNevermind 2018-03-28 20:55:07

If you write an essay in a SO answer then please add TL;DR to the top of it.

@eptx 2011-05-03 22:36:50

Functions don't support parameter defaults. Methods do. Converting from a method to a function loses parameter defaults. (Scala 2.8.1)

@corazza 2014-03-09 21:58:22

Is there are reason for this?

@Ben Lings 2010-03-27 15:53:57

One big practical difference between a method and a function is what return means. return only ever returns from a method. For example:

scala> val f = () => { return "test" }
<console>:4: error: return outside method definition
       val f = () => { return "test" }
                       ^

Returning from a function defined in a method does a non-local return:

scala> def f: String = {                 
     |    val g = () => { return "test" }
     | g()                               
     | "not this"
     | }
f: String

scala> f
res4: String = test

Whereas returning from a local method only returns from that method.

scala> def f2: String = {         
     | def g(): String = { return "test" }
     | g()
     | "is this"
     | }
f2: String

scala> f2
res5: String = is this

@Daniel C. Sobral 2010-03-27 16:07:26

That's because return is captured by the closure.

@root 2013-07-01 21:19:01

I can't think of a single time I'd want to 'return' from a function to nonlocal scope. In fact, I can see that as being a serious security issue if a function can just decide it wants to go farther back up the stack. Feels kind of like longjmp, only way easier to accidentally get wrong. I've noticed scalac won't let me return from functions, though. Does that mean this abomination has been struck from the language?

@Ben Lings 2013-07-02 08:53:52

@root - what about returning from inside a for (a <- List(1, 2, 3)) { return ... }? That gets de-sugared to a closure.

@root 2013-07-02 15:54:58

Hmm... Well, that is a reasonable use case. Still has the potential to lead to horrible difficult-to-debug problems, but that does put it in a more sensible context.

@Todd Owen 2014-12-29 02:42:57

Non-local return is also one of the better approaches when you need to "short-circuit" a fold, e.g.: stackoverflow.com/a/12897950/154770

@Ryan The Leach 2016-05-03 15:58:43

Honestly I'd use different syntax. have return return a value from the function, and some form of escape or break or continue to return from methods.

Related Questions

Sponsored Content

12 Answered Questions

[SOLVED] Pass Method as Parameter using C#

32 Answered Questions

[SOLVED] What's the difference between a method and a function?

26 Answered Questions

[SOLVED] Set a default parameter value for a JavaScript function

25 Answered Questions

[SOLVED] Difference between staticmethod and classmethod

21 Answered Questions

[SOLVED] What is the difference between call and apply?

38 Answered Questions

[SOLVED] var functionName = function() {} vs function functionName() {}

13 Answered Questions

2 Answered Questions

[SOLVED] Where does Scala look for implicits?

4 Answered Questions

[SOLVED] What is "lifting" in Scala?

Sponsored Content