You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While I was waiting on #353 and #365, I started playing with an alternative approach to group generics in a package I am working on. I think this approach may be simpler than the current proposal, and also offer several benefits.
The basic idea is to add a general mechanism by which people can define methods on sets of generics at once. This could be implemented within method<-, or using a separate function.
The simple (probably not robust) implementation I am currently using looks like this:
#' Define methods on a group of generics#'#' Takes a list of generic functions and defines the same function for each,#' allowing use of `.Generic` in the function body to refer to the actual generic.#' @param generics a list of [symbol]s (such as returned by [expression()]),#' each of which should correspond to a generic function, or the S4 definition#' of a group generic, such as [`Compare`].#' @param signature A method signature (see [`method<-`])#' @param value A function implementing each `generic` for the given `signature`.#' In each method, the variable `.Generic` in the method's environment will#' refer to the generic function.#' @noRd`group_method<-`= \(generics, signature, value) {
.generics=if (is(generics, "groupGenericFunction")) {
lapply(getGroupMembers(generics), as.symbol)
} else {
generics
}
for (genericin.generics) {
f=value
environment(f) = new.env(parent= environment(value))
environment(f)$.Generic= get(generic, mode="function")
eval(bquote(
method(.(generic), signature) <<-f
))
}
invisible(generics)
}
Then you can use any existing S4 group generic as follows (say on a toy numeric class, "MyNum"):
Since this generates all the specific methods (instead of creating a parallel dispatch on group generics), I think it makes dispatch easier to understand and easier to extend when creating class hierarchies.
It also avoids some of the ugliness common to S3 / S4 group generics code, like switch statements singling out one or two methods that operate differently. Instead, you would just define the specific methods you want to create as a separate group. e.g. if I just wanted to override inequalities, I might do:
inequalities= expression(`<`, `<=`, `>`, `>=`) # or probably new_group_generic(...) or something
group_method(inequalities, list(MyNum, MyNum)) = \(e1, e2) MyNum(value= .Generic(e1@value, e2@value))
This also avoids the need for a method to look up the actual generic function inside the implementation, and allows users to create their own groups of generics as needed.
The text was updated successfully, but these errors were encountered:
While I was waiting on #353 and #365, I started playing with an alternative approach to group generics in a package I am working on. I think this approach may be simpler than the current proposal, and also offer several benefits.
The basic idea is to add a general mechanism by which people can define methods on sets of generics at once. This could be implemented within
method<-
, or using a separate function.The simple (probably not robust) implementation I am currently using looks like this:
Then you can use any existing S4 group generic as follows (say on a toy numeric class, "MyNum"):
Since this generates all the specific methods (instead of creating a parallel dispatch on group generics), I think it makes dispatch easier to understand and easier to extend when creating class hierarchies.
It also avoids some of the ugliness common to S3 / S4 group generics code, like switch statements singling out one or two methods that operate differently. Instead, you would just define the specific methods you want to create as a separate group. e.g. if I just wanted to override inequalities, I might do:
This also avoids the need for a method to look up the actual generic function inside the implementation, and allows users to create their own groups of generics as needed.
The text was updated successfully, but these errors were encountered: