From f737a779748ddbc2a578bffc583cf600e6fa9c3d Mon Sep 17 00:00:00 2001 From: kobusbosman <40066732+kobusbosman@users.noreply.github.com> Date: Mon, 31 Jul 2023 08:34:54 +0200 Subject: [PATCH 1/9] Fix typo: then that argument is the most important --- important-args-first.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/important-args-first.qmd b/important-args-first.qmd index 2c35247..af92307 100644 --- a/important-args-first.qmd +++ b/important-args-first.qmd @@ -11,7 +11,7 @@ In a function call, the most important arguments should come first. As a general rule, the most important arguments will be the ones that are used most often, but that's often hard to tell until your function has existed in the wild for a while. Fortunately, there are a few rules of thumb that can help: -- If the output is a transformation of an input (e.g. `log()`, `stringr::str_replace()`, `dplyr::left_join()`) then that argument the most important. +- If the output is a transformation of an input (e.g. `log()`, `stringr::str_replace()`, `dplyr::left_join()`) then that argument is the most important. - Other arguments that determine the type or shape of the output are typically very important. - Optional arguments (i.e. arguments with a default) are the least important, and should come last. From c06fbf2c005a1982d57a695af56189d11d81e8d3 Mon Sep 17 00:00:00 2001 From: kobusbosman <40066732+kobusbosman@users.noreply.github.com> Date: Mon, 31 Jul 2023 08:37:15 +0200 Subject: [PATCH 2/9] Fix typo: I brought it back to life --- important-args-first.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/important-args-first.qmd b/important-args-first.qmd index af92307..668fa08 100644 --- a/important-args-first.qmd +++ b/important-args-first.qmd @@ -38,7 +38,7 @@ The vast majority of functions get this right, so we'll pick on a few examples w - ggplot2 functions work by creating an object that is then added on to a plot, so the plot, which is really the most important argument, is not obvious at all. ggplot2 works this way in part because it was written before the pipe was discovered, and the best way I came up to define plots from left to right was to rely on `+` (so-called operator overloading). - As an interesting historical fact, ggplot (the precursor to ggplot2) actually works great with the pipe, and a couple of years ago I bought it back to life as [ggplot1](https://github.com/hadley/ggplot1). + As an interesting historical fact, ggplot (the precursor to ggplot2) actually works great with the pipe, and a couple of years ago I brought it back to life as [ggplot1](https://github.com/hadley/ggplot1). ## How do I remediate past mistakes? From 9c427f025ec8fd5a080600f5d64480720ba13767 Mon Sep 17 00:00:00 2001 From: kobusbosman <40066732+kobusbosman@users.noreply.github.com> Date: Mon, 31 Jul 2023 08:37:54 +0200 Subject: [PATCH 3/9] Fix typo: to deprecate the entire function --- important-args-first.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/important-args-first.qmd b/important-args-first.qmd index 668fa08..061d90a 100644 --- a/important-args-first.qmd +++ b/important-args-first.qmd @@ -43,7 +43,7 @@ The vast majority of functions get this right, so we'll pick on a few examples w ## How do I remediate past mistakes? Generally, it is not possible to change the order of the first few arguments because it will break existing code (since these are the arguments that are mostly likely to be used unnamed). -This means that the only real solution is to dperecate the entire function and replace it with a new one. +This means that the only real solution is to deprecate the entire function and replace it with a new one. Because this is invasive to the user, it's best to do sparingly: if the mistake is minor, you're better off waiting until you've collected other problems before fixing it. For example, take `tidyr::gather()`. It has a number of problems with its design, including the argument order, that makes it harder to use. From d36048fa32e7fc5a3711780d98f42c8df1a93f44 Mon Sep 17 00:00:00 2001 From: kobusbosman <40066732+kobusbosman@users.noreply.github.com> Date: Mon, 31 Jul 2023 08:42:00 +0200 Subject: [PATCH 4/9] Fix typo: that you can easily add --- dots-after-required.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dots-after-required.qmd b/dots-after-required.qmd index 6e0ae7f..fe05ffd 100644 --- a/dots-after-required.qmd +++ b/dots-after-required.qmd @@ -14,7 +14,7 @@ This has two positive impacts: - It forces the user of your function to fully name optional arguments, because arguments that come after `...` are never matched by position or by partial name. We believe that using full names for optional arguments is good practice because it makes code easier to read. -- This in turn means that uou can easily add new optional arguments or change the order of existing arguments without affecting existing code. +- This in turn means that you can easily add new optional arguments or change the order of existing arguments without affecting existing code. ## What are some examples? From eab1559ff4dee0688c7974a934be6e1efa7b4488 Mon Sep 17 00:00:00 2001 From: kobusbosman <40066732+kobusbosman@users.noreply.github.com> Date: Mon, 31 Jul 2023 08:56:24 +0200 Subject: [PATCH 5/9] Fix typo: include in the arguments list --- defaults-short-and-sweet.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults-short-and-sweet.qmd b/defaults-short-and-sweet.qmd index d55b62f..f249b92 100644 --- a/defaults-short-and-sweet.qmd +++ b/defaults-short-and-sweet.qmd @@ -111,7 +111,7 @@ It's also nice to document it in its own file, rather than cluttering up file re ### Sentinel value {#sec-args-default-sentinel} -Sometimes a default argument has a complex calculation that you don't want to include in arguments list. +Sometimes a default argument has a complex calculation that you don't want to include in the arguments list. You'd normally use `NULL` to indicate that it's calculated by default, but `NULL` is a meaningful option. In that case, you can use a **sentinel** object. From dc14fcc14b3c690eca08494f4ce0168e910b6e26 Mon Sep 17 00:00:00 2001 From: kobusbosman <40066732+kobusbosman@users.noreply.github.com> Date: Mon, 31 Jul 2023 08:59:48 +0200 Subject: [PATCH 6/9] Fix typo: can be a valid value --- defaults-short-and-sweet.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults-short-and-sweet.qmd b/defaults-short-and-sweet.qmd index f249b92..f0f5433 100644 --- a/defaults-short-and-sweet.qmd +++ b/defaults-short-and-sweet.qmd @@ -125,7 +125,7 @@ str(rlang::zap()) Take `purrr::reduce()`: it has an optional details argument called `init`. When supplied, it serves as the initial value for the computation. -But any value (including `NULL`) can a valid value. +But any value (including `NULL`) can be a valid value. And using a sentinel value for this one case seemed like overkill. ## How do I remediate existing problems? From cd27a68fbc897dd5f38cd3a2f826c4e2368cd936 Mon Sep 17 00:00:00 2001 From: kobusbosman <40066732+kobusbosman@users.noreply.github.com> Date: Mon, 31 Jul 2023 09:01:29 +0200 Subject: [PATCH 7/9] Fix typo: what the possible values are --- enumerate-options.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enumerate-options.qmd b/enumerate-options.qmd index 94e407d..c3484cb 100644 --- a/enumerate-options.qmd +++ b/enumerate-options.qmd @@ -27,7 +27,7 @@ pkg_funs("utils") %>% funs_body_keep(has_several_ok) ## What's the pattern? If the possible values of an argument are a small set of strings, set the default argument to the set of possible values, and then use `match.arg()` or `rlang::arg_match()` in the function body. -This convention advertises to the user what the possible values, and makes it easy to generate an informative error message for inappropriate inputs. +This convention advertises to the user what the possible values are, and makes it easy to generate an informative error message for inappropriate inputs. ## What are some examples? From 62ce589ae073c50cb95d967354c3894eb5faf97e Mon Sep 17 00:00:00 2001 From: kobusbosman <40066732+kobusbosman@users.noreply.github.com> Date: Mon, 31 Jul 2023 09:04:08 +0200 Subject: [PATCH 8/9] Fix typo: how to keep defaults short --- enumerate-options.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enumerate-options.qmd b/enumerate-options.qmd index c3484cb..3a23863 100644 --- a/enumerate-options.qmd +++ b/enumerate-options.qmd @@ -111,7 +111,7 @@ rank2 <- function(x, rank2(x, ties.method = "r") ``` -### How keep defaults short? +### How to keep defaults short? This technique is a best used when the set of possible values is short. You can see that it's already getting unwieldy in `rank()`. From 9d787ab4b0811565836dce6135d2049e83ea633f Mon Sep 17 00:00:00 2001 From: kobusbosman <40066732+kobusbosman@users.noreply.github.com> Date: Mon, 31 Jul 2023 09:05:12 +0200 Subject: [PATCH 9/9] Fix typo: this technique is best used --- enumerate-options.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enumerate-options.qmd b/enumerate-options.qmd index 3a23863..7df8cac 100644 --- a/enumerate-options.qmd +++ b/enumerate-options.qmd @@ -113,7 +113,7 @@ rank2(x, ties.method = "r") ### How to keep defaults short? -This technique is a best used when the set of possible values is short. +This technique is best used when the set of possible values is short. You can see that it's already getting unwieldy in `rank()`. If you have a long list of possibilities, there are two options that you could use from @sec-defaults-short-and-sweet. Unfortunately both approaches have major downsides: