9 Comments

I hate to be pedantic, but want to point out that if we're talking about functions that work with the tidyverse, the first argument should always be the data. I think this is implicit for most users, but maybe not all?

Expand full comment
author

That's one of the considerations in https://design.tidyverse.org/important-args-first.html

Expand full comment

Does the facet_grid() function count as something that might 'break' these rules?

I use facet_grid() to tweak the aesthetics of a plot but the facet_grid() function doesn't explicitly require (or need) an argument for the base ggplot or even the source data frame.

facet_grid() works great (and is very intuitive) but I think is an exception to the first bullet of "If a function transforms some existing object, that object is most important and should be the first argument."

Expand full comment
author

That's a whooooole bigger discussion because ggplot2 doesn't use the pipe (and it probably should). Interesting ggplot would have been pipeable if the pipe had existed back then so a couple of years ago I bought it back to life as a thought experiment: https://github.com/hadley/ggplot1

I should at least mention that in this chapter though.

Expand full comment

I have always felt that the order of arguments in stringr never stayed with me. It's possible that it's because in grepl() the pattern comes before the string. But the way I most easily think about this is "pattern in string" and not "string with pattern". Rule 1 says string should be the most important, and that's why it should go first. But could there be exceptions for how natural language is used? If so, and not sure "pattern in string" holds for all languages, would this be a good example for exceptions?

Expand full comment
author

The problem is that I think that argument is weaker for gsub() where the output is even more closely related to the input vector, and you often want to do multiple replacements with separate calls, and the pipe is particularly nice. Then I think you want the replacement function to be as similar as possible to the detection function, meaning that the string should also come first there.

In general, I think how we say things in human language is a reasonable rough guiding process, but it's easily overruled by other factors because human languages can rely on context in a way that computer languages can't.

Expand full comment
Jul 21, 2023·edited Jul 22, 2023

Maybe testthat's test_that is an example of a good exception to principle 1? desc is less important than code, but since code will be a large codeblock, it seems sensible to have desc first.

Expand full comment
author
Jul 21, 2023·edited Jul 21, 2023Author

Ooh that's a good one.

Somewhat related is switching the argument order in a call so that the long thing comes last. Like:

writeLines(con = "test.txt", c(

"line1",

"line2",

"line3"

)))

Or

```

expect_snapshot(error = TRUE, {

line1

line2

line3

})

```

Expand full comment
Jul 21, 2023Liked by Hadley Wickham

On the subject of testthat, I quite recently filed an issue wondering if the order of arguments in the new `with_mocked_bindings()` should change to match how they are used in withr. Seems to be much of the same concern. https://github.com/r-lib/testthat/issues/1834

Expand full comment