Generally speaking, method invocation in Scala follows Java conventions.In other words, there should not be a space between the invocationtarget and the dot (.
), nor a space between the dot and the methodname, nor should there be any space between the method name and theargument-delimiters (parentheses). Each argument should be separated bya single space following the comma (,
):
foo(42, bar)
target.foo(42, bar)
target.foo()
As of version 2.8, Scala now has support for named parameters. Namedparameters in a method invocation should be treated as regularparameters (spaced accordingly following the comma) with a space oneither side of the equals sign:
foo(x = 6, y = 7)
While this style does create visual ambiguity with named parameters andvariable assignment, the alternative (no spacing around the equals sign)results in code which can be very difficult to read, particularly fornon-trivial expressions for the actuals.
Arity-0
Scala allows the omission of parentheses on methods of arity-0 (noarguments):
reply()
// is the same as
reply
However, this syntax should only be used when the method in questionhas no side-effects (purely-functional). In other words, it would beacceptable to omit parentheses when calling queue.size
, but not whencalling println()
. This convention mirrors the method declarationconvention given above.
Religiously observing this convention will dramatically improve codereadability and will make it much easier to understand at a glance themost basic operation of any given method. Resist the urge to omitparentheses simply to save two characters!
Postfix Notation
Scala allows methods that take no arguments to be invoked using postfix notation:
// recommended
names.toList
// discourage
names toList
This style is unsafe, and should not be used. Since semicolons areoptional, the compiler will attempt to treat it as an infix methodif it can, potentially taking a term from the next line.
names toList
val answer = 42 // will not compile!
This may result in unexpected compile errors at best, and happilycompiled faulty code at worst. Although the syntax is used by someDSLs, it should be considered deprecated, and avoided.
Since Scala 2.10, using postfix operator notation will result in acompiler warning.
Arity-1 (Infix Notation)
Scala has a special punctuation-free syntax for invoking methods of arity-1(one argument). This should generally be avoided, but with the followingexceptions for operators and higher-order functions. In these cases it shouldonly be used for purely-functional methods (methods with no side-effects).
// recommended
names.mkString(",")
// also sometimes seen; controversial
names mkString ","
// wrong - has side-effects
javaList add item
Symbolic Methods/Operators
Symbolic methods (operators) should always be invoked using infix notation withspaces separating the target, the operator, and the parameter:
// right!
"daniel" + " " + "spiewak"
a + b
// wrong!
"daniel"+" "+"spiewak"
a+b
a.+(b)
For the most part, this idiom follows Java and Haskell syntactic conventions. Agray area is short, operator-like methods like max
, especially if commutative:
// fairly common
a max b
Symbolic methods which take more than one parameter (they do exist!)may still be invoked using infix notation, delimited by spaces:
foo ** (bar, baz)
Such methods are fairly rare, however, and should normally be avoided during APIdesign. For example, the use of the /:
and :\
methods should be avoided inpreference to their better-known names, foldLeft
and foldRight
.
Higher-Order Functions
As noted, methods which take functions as parameters (such as map
orforeach
) should be invoked using infix notation. It is also possible toinvoke such methods in the following way:
// wrong!
names.map { _.toUpperCase }
This style is not the accepted standard! The reason to avoid this style is forsituations where more than one invocation must be chained together:
// wrong!
names.map { _.toUpperCase }.filter { _.length > 5 }
// right!
names map { _.toUpperCase } filter { _.length > 5 }
Both of these work, but the former can easily lead to confusion. Thesub-expression { _.toUpperCase }.filter
when taken in isolation looks like weare invoking the filter
method on a function value. However, we are actuallyinvoking filter
on the result of the map
method, which takes the functionvalue as a parameter.