Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the rule for parenthesis in Scala method invocation?

Tags:

scala

Isn't toList a method that converts something into a List?

If yes so why can't I use parenthesis with it? I must be missing something more fundamental here.

Here is the example:

val l = Array(1,2,3).toList // works fine  val l = Array(1,2,3).toList() // gives the error below 

Not enough arguments for method apply: (n: Int)Int in trait LinearSeqOptimized. Unspecified value parameter n.

like image 254
TraderJoeChicago Avatar asked Jul 10 '11 18:07

TraderJoeChicago


People also ask

What does => mean in scala?

=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class. For example, the type Int => String , is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String .

How do you call a method in scala?

Method Invocation is a technique that demonstrates different syntax in which we dynamically call methods of a class with an object. There should not be any space between the invocation object/target and the dot(.) nor a space between the dot and method name.

What is the syntax of defining method in scala?

Syntax. def functionName ([list of parameters]) : [return type] = { function body return [expr] } Here, return type could be any valid Scala data type and list of parameters will be a list of variables separated by comma and list of parameters and return type are optional.

What kind of parameters are not needed while calling a method in scala?

A parameterless method is a function that does not take parameters, defined by the absence of any empty parenthesis. Invocation of a paramaterless function should be done without parenthesis. This enables the change of def to val without any change in the client code which is a part of uniform access principle.


2 Answers

If a method is defined as

def toList = { /* something */ } 

then it must be called as

object.toList 

with no extra parentheses. We say that this method has zero parameter lists.

We could also define a parameter list but put nothing in it:

def toList() = { /* something */ } 

Now, we could call either of

object.toList() object.toList 

since Scala allows the shortcut of omitting parentheses on method calls.

As far as the JVM is concerned, there is no difference between the first definition ("zero parameter lists") and the second ("one empty parameter list"). But Scala maintains a distinction. Whether this is a good idea or not is debatable, but the motivation might be clearer when you realize that we can also

def toList()() = { /* something */ } 

which is known as two empty parameter lists, and then call any of

object.toList()() object.toList() object.toList 

and now, if we were to convert this into a function, we would type it as

() => () => T   /* T is the return value of the something */ 

while the second definition would be

() => T 

which is clearly different conceptually, even if practically you use it the same way (put in nothing and sooner or later get out a T).

Anyway, toList doesn't need any parameters, and the Scala standard is to leave off the parens unless the method changes the object itself (rather than just returning something), so it's def toList without any parens afterwards. And thus you can only call it as object.toList.

like image 182
Rex Kerr Avatar answered Sep 23 '22 13:09

Rex Kerr


Your second line is actually interpreted as

val l = Array(1,2,3).toList.apply() 

since foo(x) is "magic" syntax for foo.apply(x).

That's why the complier complains about "not enough arguments", as the apply method on lists takes one argument.

Thus you can write e.g.:

scala> val i = Array(1, 2, 3).toList(1) i: Int = 2 
like image 22
Knut Arne Vedaa Avatar answered Sep 23 '22 13:09

Knut Arne Vedaa