diff --git a/_style/declarations.md b/_style/declarations.md index 85bcd995b4..06fbfadcb7 100644 --- a/_style/declarations.md +++ b/_style/declarations.md @@ -13,7 +13,7 @@ next-page: control-structures ## Classes -Class/Object/Trait constructors should be declared all on one line, +Class, object, and trait constructors should be declared all on one line, unless the line becomes "too long" (about 100 characters). In that case, put each constructor argument on its own line with [trailing commas](https://docs.scala-lang.org/sips/trailing-commas.html#motivation): @@ -102,7 +102,7 @@ Local methods or private methods may omit their return type: #### Procedure Syntax -Avoid the procedure syntax, as it tends to be confusing for very little gain in brevity. +Avoid the (now deprecated) procedure syntax, as it tends to be confusing for very little gain in brevity. // don't do this def printBar(bar: Baz) { @@ -160,7 +160,7 @@ or is of a non-functional nature (some mutable state, local or otherwise), the body must be enclosed in braces: def sum(ls: List[String]): Int = { - val ints = ls map (_.toInt) + val ints = ls.map(_.toInt) ints.foldLeft(0)(_ + _) } @@ -197,7 +197,8 @@ There are three main reasons you should do this: Multiple parameter lists allow you to create your own "control structures": - def unless(exp: Boolean)(code: => Unit): Unit = if (!exp) code + def unless(exp: Boolean)(code: => Unit): Unit = + if (!exp) code unless(x < 5) { println("x was not less than five") } @@ -223,7 +224,7 @@ There are three main reasons you should do this: List("").foldLeft(0, (b: Int, a: String) => b + a.length) List("").foldLeft[Int](0, _ + _.length) -For complex DSLs, or with type-names that are long, it can be difficult +For complex DSLs, or with type names that are long, it can be difficult to fit the entire signature on one line. For those cases there are several different styles in use: diff --git a/_style/method-invocation.md b/_style/method-invocation.md index 861d07dba6..eb1e548785 100644 --- a/_style/method-invocation.md +++ b/_style/method-invocation.md @@ -51,7 +51,7 @@ acceptable to omit parentheses when calling `queue.size`, but not when calling `println()`. This convention mirrors the method declaration convention given above. -Religiously observing this convention will *dramatically* improve code +Observing this convention improves code 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! @@ -92,35 +92,28 @@ gray 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: +Symbolic methods which take more than one parameter are discouraged. +When they exist, they 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 API -design. For example, the use of the `/:` and `:\` methods should be avoided in +design. For example, the use of the (now deprecated) `/:` and `:\` methods should be avoided in preference to their better-known names, `foldLeft` and `foldRight`. ### 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: +Invoking higher-order functions may use parens or braces, but in +either case, use dot notation and omit any space after the method name: - // wrong! - names.map { _.toUpperCase } - -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: + names.map(_.toUpperCase) - // wrong! - names.map { _.toUpperCase }.filter { _.length > 5 } +These are not recommended: - // right! - names map { _.toUpperCase } filter { _.length > 5 } + // wrong! missing dot + names map (_.toUpperCase) + // wrong! extra space + names.map (_.toUpperCase) -Both of these work, but the former can easily lead to confusion. The -sub-expression `{ _.toUpperCase }.filter` when taken in isolation looks 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. +Experience has shown that these styles make code harder to read, +especially when multiple such method calls are chained. diff --git a/_style/types.md b/_style/types.md index 87b9a1eb3d..67df05af71 100644 --- a/_style/types.md +++ b/_style/types.md @@ -38,7 +38,7 @@ Function values support a special case of type inference which is worth calling out on its own: val ls: List[String] = ... - ls map (str => str.toInt) + ls.map(str => str.toInt) In cases where Scala already knows the type of the function value we are declaring, there is no need to annotate the parameters (in this case,