From a3732aad5176d6ca34af33437f5525fcb816ef71 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 27 Feb 2017 14:22:36 -0800 Subject: [PATCH 1/2] style guide: revise sections on infix and postfix notation the postfix text is mostly the same, but now uses the word "postfix" instead of "suffix" the infix text is totally rewritten and now more strongly discourages use of infix for alphabetic method names. back when the style guide was first written, I think there was more experimentation with, and more acceptance of, such use of infix notation. these days, not so much. I omitted the material about mixing dot and dotless notation -- the "a b.(c) d" example. I found that passage highly confusing and I've seen others be confused by it as well. --- style/method-invocation.md | 103 ++++++++++++------------------------- 1 file changed, 32 insertions(+), 71 deletions(-) diff --git a/style/method-invocation.md b/style/method-invocation.md index 13dc3c7f2e..2fa31221da 100644 --- a/style/method-invocation.md +++ b/style/method-invocation.md @@ -54,19 +54,19 @@ 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 +## Postfix Notation -Scala allows methods of arity-0 to be invoked using suffix notation: +Scala allows methods that take no arguments to be invoked using postfix notation: + // recommended names.toList - // is the same as - - names toList // Unsafe, don't use! + // discourage + names toList 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. +if it can, potentially taking a term from the next line. names toList val answer = 42 // will not compile! @@ -75,83 +75,44 @@ 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. -As of Scala 2.10, using suffix operator notation will result in a compiler warning. - -## Arity-1 - -Scala has a special syntax for invoking methods of arity-1 (one -argument): - - 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)) - names mkString "," - optStr getOrElse "" - - // wrong! - javaList add item +Since Scala 2.10, using postfix operator notation will result in a +compiler warning. -### Higher-Order Functions +## Infix notation -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: +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.map (_.toUpperCase) // wrong! + // recommended + a + b -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: + // legal, but less readable + a+b - // wrong! - names.map (_.toUpperCase).filter (_.length > 5) + // legal, but definitely strange + a.+(b) - // right! - names map (_.toUpperCase) filter (_.length > 5) +but avoid it for almost all alphabetic-named methods: -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. - -## Symbolic methods/Operators - -Methods with symbolic names should *always* be invoked using infix -notation with spaces separating the target, the symbolic method and the -parameter: + // recommended + names.mkString(",") - // right! - "daniel" + " " + "Spiewak" + // also sometimes seen; controversial + names mkString "," - // wrong! - "daniel"+" "+"spiewak" +A gray area is short, operator-like methods like `max`, +especially if commutative: -For the most part, this idiom follows Java and Haskell syntactic -conventions. + // fairly common + a max b Symbolic methods which take more than one parameter (they do exist!) -should still be invoked using infix notation, delimited by spaces: +may still be invoked using infix notation, delimited by spaces: foo ** (bar, baz) -Such methods are fairly rare, however, and should be avoided during API -design. - -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. +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`. From aaa9d8b2654f79679164bd5429199ae587c9df12 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 27 Feb 2017 14:23:22 -0800 Subject: [PATCH 2/2] discuss postfix notation second, since it's less important --- style/method-invocation.md | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/style/method-invocation.md b/style/method-invocation.md index 2fa31221da..9558a78241 100644 --- a/style/method-invocation.md +++ b/style/method-invocation.md @@ -54,30 +54,6 @@ 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! -## 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 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. - -Since Scala 2.10, using postfix operator notation will result in a -compiler warning. - ## Infix notation Scala has a special punctuation-free syntax for invoking methods that @@ -116,3 +92,27 @@ 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`. + +## 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 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. + +Since Scala 2.10, using postfix operator notation will result in a +compiler warning.