diff --git a/style/method-invocation.md b/style/method-invocation.md index 13dc3c7f2e..9558a78241 100644 --- a/style/method-invocation.md +++ b/style/method-invocation.md @@ -54,104 +54,65 @@ readability and will make it much easier to understand at a glance the most basic operation of any given method. Resist the urge to omit parentheses simply to save two characters! -### Suffix Notation +## Infix notation -Scala allows methods of arity-0 to be invoked using suffix notation: +Scala has a special punctuation-free syntax for invoking methods that +take one argument. Many Scala programmers use this notation for +symbolic-named methods: - names.toList - - // is the same as - - names toList // Unsafe, don't use! - -This style is unsafe, and should not be used. Since semicolons are -optional, the compiler will attempt to treat it as an infix method -if 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 happily -compiled faulty code at worst. Although the syntax is used by some -DSLs, it should be considered deprecated, and avoided. + // recommended + a + b -As of Scala 2.10, using suffix operator notation will result in a compiler warning. + // legal, but less readable + a+b -## Arity-1 + // legal, but definitely strange + a.+(b) -Scala has a special syntax for invoking methods of arity-1 (one -argument): +but avoid it for almost all alphabetic-named methods: + // recommended names.mkString(",") - // is the same as - - names mkString "," - -This syntax is formally known as "infix notation". It should *only* be -used for purely-functional methods (methods with no side-effects) - such -as `mkString` -or methods which take functions as parameters - such as -`foreach`: - - // right! - names foreach (n => println(n)) + // also sometimes seen; controversial names mkString "," - optStr getOrElse "" - - // wrong! - javaList add item - -### Higher-Order Functions - -As noted, methods which take functions as parameters (such as `map` or -`foreach`) should be invoked using infix notation. It is also *possible* -to invoke such methods in the following way: - - names.map (_.toUpperCase) // wrong! -This style is *not* the accepted standard! The reason to avoid this -style is for situations where more than one invocation must be chained -together: +A gray area is short, operator-like methods like `max`, +especially if commutative: - // wrong! - names.map (_.toUpperCase).filter (_.length > 5) + // fairly common + a max b - // right! - names map (_.toUpperCase) filter (_.length > 5) +Symbolic methods which take more than one parameter (they do exist!) +may still be invoked using infix notation, delimited by spaces: -Both of these work, but the former exploits an extremely unintuitive -wrinkle in Scala's grammar. The sub-expression -`(_.toUpperCase).filter` when taken in isolation looks for all the -world like we are invoking the `filter` method on a function value. -However, we are actually invoking `filter` on the result of the `map` -method, which takes the function value as a parameter. This syntax is -confusing and often discouraged in Ruby, but it is shunned outright in -Scala. + foo ** (bar, baz) -## Symbolic methods/Operators +Such methods are fairly rare, however, and should normally be avoided +during API design. For example, the use of the `/:` and `:\` methods +should be avoided in preference to their better-known names, +`foldLeft` and `foldRight`. -Methods with symbolic names should *always* be invoked using infix -notation with spaces separating the target, the symbolic method and the -parameter: +## Postfix Notation - // right! - "daniel" + " " + "Spiewak" +Scala allows methods that take no arguments to be invoked using postfix notation: - // wrong! - "daniel"+" "+"spiewak" + // recommended + names.toList -For the most part, this idiom follows Java and Haskell syntactic -conventions. + // discourage + names toList -Symbolic methods which take more than one parameter (they do exist!) -should still be invoked using infix notation, delimited by spaces: +This style is unsafe, and should not be used. Since semicolons are +optional, the compiler will attempt to treat it as an infix method +if it can, potentially taking a term from the next line. - foo ** (bar, baz) + names toList + val answer = 42 // will not compile! -Such methods are fairly rare, however, and should be avoided during API -design. +This may result in unexpected compile errors at best, and happily +compiled faulty code at worst. Although the syntax is used by some +DSLs, it should be considered deprecated, and avoided. -Finally, the use of the `/:` and `:\` should be avoided in preference to -the more explicit `foldLeft` and `foldRight` method of `Iterator`. The -right-associativity of the `/:` can lead to extremely confusing code, at -the benefit of saving a few characters. +Since Scala 2.10, using postfix operator notation will result in a +compiler warning.