Skip to content

Update Style Guide "Invocation" section and TOC #1451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion _style/control-structures.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ overview-name: "Style Guide"

num: 7

previous-page: files
previous-page: declarations
next-page: method-invocation
---

Expand Down
12 changes: 6 additions & 6 deletions _style/declarations.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ title: Declarations
partof: style
overview-name: "Style Guide"

num: 9
num: 6

previous-page: method-invocation
next-page: scaladoc
previous-page: nested-blocks
next-page: control-structures
---

## Classes
Expand Down Expand Up @@ -51,7 +51,7 @@ empty line should be added to further separate extensions from class implementat
with Logging
with Identifiable
with Serializable {

def firstMethod: Foo = …
}

Expand Down Expand Up @@ -286,11 +286,11 @@ function value.

When styles (1) and (4) are used exclusively, it becomes very easy to
distinguish places in the source code where function values are used.
Both styles make use of parentheses, since they look clean on a single line.
Both styles make use of parentheses, since they look clean on a single line.

### Spacing

There should be no space between parentheses and the code they contain.
There should be no space between parentheses and the code they contain.
Curly braces should be separated from the code within them by a one-space gap,
to give the visually busy braces "breathing room".

Expand Down
6 changes: 3 additions & 3 deletions _style/files.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ title: Files
partof: style
overview-name: "Style Guide"

num: 6
num: 9

previous-page: nested-blocks
next-page: control-structures
previous-page: method-invocation
next-page: scaladoc
---

As a rule, files should contain a *single* logical compilation unit. By
Expand Down
14 changes: 7 additions & 7 deletions _style/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ This document is intended to outline some basic Scala stylistic guidelines which
- [Annotations](types.html#annotations)
- [Ascription](types.html#ascription)
- [Functions](types.html#functions)
- [Arity-1](types.html)
- [Arity-1](types.html#arity-1)
- [Structural Types](types.html#structural-types)
- [Nested Blocks](nested-blocks.html)
- [Curly Braces](nested-blocks.html#curly-braces)
Expand All @@ -40,10 +40,11 @@ This document is intended to outline some basic Scala stylistic guidelines which
- [Classes](declarations.html#classes)
- [Ordering Of Class Elements](declarations.html#ordering-of-class-elements)
- [Methods](declarations.html#methods)
- [Procedure Syntax](declarations.html#procedure-syntax)
- [Modifiers](declarations.html#modifiers)
- [Body](declarations.html#body)
- [Multiple Parameter Lists](declarations.html#multiple-parameter-lists)
- [Higher-Order Functions](declarations.html)
- [Higher-Order Functions](declarations.html#higher-order-functions)
- [Fields](declarations.html#fields)
- [Function Values](declarations.html#function-values)
- [Spacing](declarations.html#spacing)
Expand All @@ -54,11 +55,10 @@ This document is intended to outline some basic Scala stylistic guidelines which
- [Trivial Conditionals](control-structures.html#trivial-conditionals)
- [Method Invocation](method-invocation.html)
- [Arity-0](method-invocation.html#arity-0)
- [Infix Notation](method-invocation.html#infix-notation)
- [Postfix Notation](method-invocation.html)
- [Arity-1](method-invocation.html)
- [Higher-Order Functions](method-invocation.html)
- [Symbolic methods/Operators](method-invocation.html)
- [Postfix Notation](method-invocation.html#postfix-notation)
- [Arity-1 (Infix Notation)](method-invocation.html#arity-1-infix-notation)
- [Symbolic Methods/Operators](method-invocation.html#symbolic-methodsoperators)
- [Higher-Order Functions](method-invocation.html#higher-order-functions)
- [Files](files.html)
- [Multi-Unit Files](files.html#multi-unit-files)
- [Scaladoc](scaladoc.html)
Expand Down
98 changes: 64 additions & 34 deletions _style/method-invocation.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ overview-name: "Style Guide"
num: 8

previous-page: control-structures
next-page: declarations
next-page: files
---

Generally speaking, method invocation in Scala follows Java conventions.
Expand Down Expand Up @@ -56,31 +56,62 @@ 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!

## Infix notation
### Postfix 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:
Scala allows methods that take no arguments to be invoked using postfix notation:

// recommended
a + b
names.toList

// legal, but less readable
a+b
// discourage
names toList

// legal, but definitely strange
a.+(b)
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.

but avoid it for almost all alphabetic-named methods:
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.

## 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 following
exceptions for operators and higher-order functions. In these cases it should
only be used for purely-functional methods (methods with no side-effects).

// recommended
names.mkString(",")

// also sometimes seen; controversial
names mkString ","

A gray area is short, operator-like methods like `max`,
especially if commutative:
// wrong - has side-effects
javaList add item

### Symbolic Methods/Operators

Symbolic methods (operators) should always be invoked using infix notation with
spaces 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. A
gray area is short, operator-like methods like `max`, especially if commutative:

// fairly common
a max b
Expand All @@ -90,31 +121,30 @@ 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 preference to their better-known names,
`foldLeft` and `foldRight`.

## Postfix Notation
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`.

Scala allows methods that take no arguments to be invoked using postfix notation:
### Higher-Order Functions

// recommended
names.toList
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:

// discourage
names toList
// wrong!
names.map { _.toUpperCase }

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.
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 toList
val answer = 42 // will not compile!
// wrong!
names.map { _.toUpperCase }.filter { _.length > 5 }

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.
// right!
names map { _.toUpperCase } filter { _.length > 5 }

Since Scala 2.10, using postfix operator notation will result in a
compiler warning.
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.
2 changes: 1 addition & 1 deletion _style/nested-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ overview-name: "Style Guide"
num: 5

previous-page: types
next-page: files
next-page: declarations
---

## Curly Braces
Expand Down
2 changes: 1 addition & 1 deletion _style/scaladoc.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ overview-name: "Style Guide"

num: 10

previous-page: declarations
previous-page: files
---

It is important to provide documentation for all packages, classes,
Expand Down