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

Method consistency changes #85

Closed
hadley opened this issue Oct 27, 2021 · 7 comments · Fixed by #141
Closed

Method consistency changes #85

hadley opened this issue Oct 27, 2021 · 7 comments · Fixed by #141

Comments

@hadley
Copy link
Member

hadley commented Oct 27, 2021

To support discussion in #7:

library(R7)

foo1 <- new_generic("foo1", fun = function(x, ...) {
  method_call()
})
# Should be ok: ... in generic just indicate that methods can have
# additional arguments
method(foo1, "character") <- function(x) ""
#> Error: `method` must be consistent with <R7_generic> foo1.
#> - `generic` has `...`
#> - `method` does not have `...`

foo2 <- new_generic("foo2", fun = function(x) {
  method_call()
})
# Should error: generic doesn't have dots
method(foo2, "character") <- function(x, y = 1) ""

foo3 <- new_generic("foo3", fun = function(x, ..., y = TRUE) {
   method_call()
})
# Should error: no y argument
method(foo3, "foo3") <- function(x, ...) ""

Created on 2021-10-27 by the reprex package (v2.0.1)

@hadley
Copy link
Member Author

hadley commented Oct 27, 2021

A related question is whether supplying signature should generate a generic with or without ...

@krlmlr
Copy link
Contributor

krlmlr commented Oct 30, 2021

I'm confused by the mean2 example in ?new_generic, specifically "If you want to require methods implement additional arguments":

  • Do arguments after the ellipsis have a special meaning?
  • Do they have to exist in each method?

Interface evolution was very difficult in DBI.

@hadley
Copy link
Member Author

hadley commented Nov 1, 2021

Arguments after ... don't have a special meaning, but by convention that's where you put extra arguments. These would be required in every method.

@hadley
Copy link
Member Author

hadley commented Dec 13, 2021

Notes from meeting:

Proposed principle: If a generic has ..., the formals of the method must be the formals the of generic + extra arguments. If a generic doesn't have ..., the formals of the method must be identical to the formals of the generic.

Would make sense for methods to supply defaults since the generic often does not have enough information to supply. For example, generalise of something like digits to precision, where the default for dates/times would be specified differently to numbers.

@DavisVaughan
Copy link
Collaborator

DavisVaughan commented Dec 13, 2021

In dplyr, for example, we have summarise() which has a .groups argument in the generic, but the dtplyr method doesn't have that. I guess this would be disabled?

> dplyr::summarise
function (.data, ..., .groups = NULL) 
{
    UseMethod("summarise")
}
<bytecode: 0x7fb9ba5ceb88>
<environment: namespace:dplyr>

> dtplyr:::summarise.dtplyr_step
function (.data, ...) 
{

@DavisVaughan
Copy link
Collaborator

If a generic has ..., the formals of the method must be the formals the of generic + extra arguments.

Do the "extra arguments" have to come after the dots?

predict() is an interesting example. The generic is predict(object, ...), but in tidymodels we have predict.model_spec(object, new_data, type = NULL, opts = list(), ...) which has:

  • An extra required argument, new_data
  • A few extra optional arguments
  • All of which are before the dots

@lawremi
Copy link
Collaborator

lawremi commented Jan 10, 2022

The method formals would not need to include ..., so I am not sure if this case applies.

hadley added a commit that referenced this issue Jan 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants