Skip to content
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

Recommend single indent, not double indent #223

Merged
merged 4 commits into from
Oct 2, 2024
Merged
Changes from 3 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
63 changes: 48 additions & 15 deletions functions.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -32,35 +32,36 @@ map(xs, ~ mean((.x + 5)^2))
* Avoid using `\()` except for anonymous functions.
* Avoid using `\()` in a pipe.

## Long lines
## Multi-line function defintions

There are two options if the function name and definition can't fit on a single line:
There are two options if the function name and definition can't fit on a single line. In both cases, each argument goes on its own; the difference is how deep you indent it and where you put `)` and `{`:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
There are two options if the function name and definition can't fit on a single line. In both cases, each argument goes on its own; the difference is how deep you indent it and where you put `)` and `{`:
There are two options if the function name and definition can't fit on a single line. In both cases, each argument goes on its own line; the difference is how deep you indent it and where you put `)` and `{`:


* Function-indent: place each argument on its own line, and indent to match the opening `(` of `function`:
* **Single-indent**: indent the argument name with a single indent (i.e. two spaces).
The trailing `)` and leading `{` go on a new line.

```{r, eval = FALSE}
long_function_name <- function(a = "a long argument",
b = "another argument",
c = "another long argument") {
# Good
long_function_name <- function(
a = "a long argument",
b = "another argument",
c = "another long argument"
) {
# As usual code is indented by two spaces.
}
```

* Double-indent: Place each argument of its own **double** indented line.
* **Function-indent**: indent the argument name to match the opening `(` of `function`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW we use the term hanging_indent_style in {lintr}:

https://lintr.r-lib.org/reference/indentation_linter.html

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah I like that better.

The trailing `)` and leading `{` go on the same line as the last argument.

```{r, eval = FALSE}
long_function_name <- function(
a = "a long argument",
b = "another argument",
c = "another long argument") {
# Bad
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to add # Bad? It's currently just another option right? (Same with # Good above)?

i.e. while i feel like we are starting to prefer single-indent, im not sure we are all in on it enough for the style guide to recommend that function-indent is # Bad

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, no I meant to write good.

long_function_name <- function(a = "a long argument",
b = "another argument",
c = "another long argument") {
# As usual code is indented by two spaces.
}
```

In both cases the trailing `)` and leading `{` should go on the same line as the last argument.

Prefer function-indent style to double-indent style when it fits.

These styles are designed to clearly separate the function definition from its body.

```{r, eval = FALSE}
Expand All @@ -75,6 +76,38 @@ long_function_name <- function(a = "a long argument",

If a function argument can't fit on a single line, this is a sign you should rework the argument to keep it [short and sweet](https://design.tidyverse.org/defaults-short-and-sweet.html).

## S7

In S7, the method definition can be long because the function name is replaced by a method call that specifies the generic and dispatch classes. In this case we recommend the single-indent style.

```{r, eval = FALSE}
method(from_provider, list(openai_provider, class_any)) <- function(
provider,
x,
...,
error_call = caller_env()
) {
...
}
```

If the method definition is too long to fit on one line, use the usual rules to
spread the method arguments across multiple lines:

```{r, eval = FALSE}
method(
from_provider,
list(openai_provider, class_any, a_very_long_class_name)
) <- function(
provider,
x,
...,
error_call = caller_env()
) {
...
}
```

## `return()`

Only use `return()` for early returns. Otherwise, rely on R to return the result
Expand Down
Loading