0

Below are two methods that are declared in different style. Both are doing the same work. I am wondering, why

  1. different syntax is required to check type of function (yellow block)
  2. different syntax is required to call function (green block)
  3. declaration of both methods on scala repl gives different results (red block)

Also, please suggest, which one is the preferred way to declare methods or are there any special use cases for both the styles of method declaration?

enter image description here


Edit 1:

Below are the commands from screenshot :-

Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_79).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def add(x:Int, y :Int): Int = {x+y}
add: (x: Int, y: Int)Int

scala> def sum = (x:Int, y:Int) => {x+y}
sum: (Int, Int) => Int

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

scala> :t add(_, _)
(Int, Int) => Int

scala> :t sum
(Int, Int) => Int

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

scala> add(_, _)
res1: (Int, Int) => Int = <function2>

scala> sum
res2: (Int, Int) => Int = <function2>

Edit 2:

@Shadowlands

i have read on dzone, that states "when a function is expected but a method is provided, it will be automatically converted into a function. This is called the ETA expansion.".

Now, if ETA takes care to convert your methods to function. Is it really required to use sum style, because it looks like an additional overhead of Function<> object.

mogli
  • 1,549
  • 4
  • 29
  • 57

2 Answers2

2

Simply put, add is a function that takes two Int arguments and returns an Int result, while sum is a 0-argument function that returns a new function that, in turn, takes two Int arguments and returns an Int result. Indeed, sum could readily be defined as:

def sum = add _

As to which way to define your functions, this depends on how it is to be used. Generally, use the add style most of the time, as it is easier to understand and work with. If, however, you will be passing the function as an argument to another function, then the sum-style formulation can be more convenient and may convey more of your intent on how the function is expected to be used.

Shadowlands
  • 14,994
  • 4
  • 45
  • 43
  • i have read https://dzone.com/articles/revealing-scala-magician%E2%80%99s, that "when a function is expected but a method is provided, it will be automatically converted into a function. This is called the ETA expansion.". Now, if ETA takes care to convert your methods to function. Is it really required to use sum style, because it looks like an additional overhead of Function<> object. – mogli Aug 08 '15 at 00:45
  • 1
    @rits No, it certainly isn't required! There just may be times when it is useful as, for example, an indicator of how you expect it to be used, or you might be defining an implicit value to then be passed on automatically as an implicit argument to an appropriately-typed function. – Shadowlands Aug 08 '15 at 06:51
  • @rits Hmm, comments aren't really meant for whole multiline examples, so I'll try something brief (and rather contrived). Imagine a method defined as `def operate(x:Int, y :Int)(implicit op: (Int, Int) => Int): Int = op(x, y)`. You might then set up your code to read a flag and use it to decide which op you want used, eg: `implicit val op = if (flag) add _ else someOtherOp _`, then later when you call `operate(x,y)`, the method will execute the implicit operation you selected earlier. – Shadowlands Aug 08 '15 at 07:27
  • As of now, i don't know the concept of implicit keyword. Probably, after learning about this keyword, i would be able to understand your example. If fails to understand, i will open a new question on stackoverflow :) – mogli Aug 08 '15 at 09:38
1

This is how REPL is implemented. The code that you type is wrapped in object. Thus your def add becomes method of this object, while def sum is a method that returns Function. When you are addressing add like this: add(_, _) you are addressing method, while when you are addressing sum as sum you are addressing result of sum's execution, which is function.

Differences between methods and functions are described here.

PS. Try to check the type of sum _

Community
  • 1
  • 1
Aivean
  • 10,692
  • 25
  • 39
  • "Try to check the type of sum _". this line really helped me to understand the concept. Upvoting your answer. Thanks. – mogli Aug 08 '15 at 09:40