[Rd] Feature request: mixing `...` (three dots) with other formal arguments in S4 methods
Janko Thyson
janko.thyson at gmail.com
Fri Nov 28 03:53:39 CET 2014
Well, the benefit lies in the ability to pass along arguments via `...` to
more than one recipient that use *identical argument names* and/or when
these recipients are not necessarily located on the same calling stack
layer.
I'm *not* after a *general* change in the way arguments are
dispatched/functions are called as I'm actually a big friend of keepings
things quite explicit (thus declaring explicitly what's passed on to
subsequent functions by defining respective formal arguments).
Nevertheless, sometimes it's quite handy to use `...`.
Consider the implementation of `plot()`. It uses `...` quite extensively to
pass things along to `par()` which makes perfect sense: declaring formal
arguments for things that are merely passed along to `par()` in *all*
functions that depend on `par()` would probably be a developer's nightmare
w.r.t. refactoring should `par()` ever change.
But let's say that at one point in time, developers decide that `par()` can
also call something like `parShiny()` if `shiny = TRUE` in order
encapsulate shiny-specific graphical parameters in a own function (sorry, I
couldn't come up with a better example just now). I'm using a simplified
example where `cex` is indeed a formal parameter (which is not the case in
the actual `par()`):
myPlot <- function(x, ...) {
myPar(...)
}
myPar <- function (cex = 1.0, shiny = FALSE, ...) {
if (!shiny) {
message("myPar/cex:")
print(cex)
} else {
parShiny(...)
}
}
parShiny <- function (cex = 1.0) {
message("parShiny/cex:")
print(cex)
}
> myPlot(x = 10, cex = 1.25)
myPar/cex:
[1] 1.25
> myPlot(x = 10, cex = 1.25, shiny = TRUE)
parShiny/cex:
[1] 1
So: due to the fact that `myPar()` has a formal argument `cex`, `...` is
out of the question for passing along `cex` to `parShiny()`. You'd have to
change things to `parShiny(cex = cex)` in the implementation of `myPar()`
in order for this to work as expected - which you might or might not feel
is (too) cumbersome.
While it probably makes a lot of sense to pass things along explicitly in
95 % of cases, there might be situations where you'd prefer to being able
to use `...`.
But I don't want to overstress the (current) purpose/use case behind my
request. I just wondered if the limitation of not being able to mix `...`
with other formal arguments could be lifted soon as the possiblity is
already stated at `?dotsMethods` :-)
On Fri, Nov 28, 2014 at 2:40 AM, Gabriel Becker <gmbecker at ucdavis.edu>
wrote:
> I think I understand what you're saying now, but I'm still kind of missing
> the benefit from the approach.
>
> As far as I can tell just giving foo formals for the arguments you want it
> to catch gives you the end result you want, doesn't it?
>
> And if the generic has ... in it, you can (if you're very careful) add
> formals to specific methods that would capture arguments not meant for
> other methods of the same generic.
>
> ~G
>
> On Thu, Nov 27, 2014 at 11:26 AM, Janko Thyson <janko.thyson at gmail.com>
> wrote:
>
>> Hi Gabriel,
>>
>> and thanks for answering. I'm basically just trying to find a way to use
>> the power of `...` in more complex scenarios and I'm well aware that this
>> might not be the best approach ;-)
>>
>> Regarding your actual question:
>> "Are you suggesting methods be dispatched based on the *contents* of ...
>> [...]?"
>> Yes, I guess currently I kind of do - but not on the argument *names*
>>
>> I'm not expecting functions to detect the argument *names* from `...`,
>> but the relevant "argument containers" from which then the actual arguments
>> should be extracted and used:
>>
>> I thought the *actual* arguments to be passed via `...` to subsequent
>> functions/methods could be put into an "arguments container" (as a list so
>> you could easily use them with `do.call(foo)`) that has a class that `foo`
>> expects for its `...` argument (e.g. `ThreedotsForFoo`). What I would like
>> to accomplish is that `foo` auto-detects those parts coming in via `...`
>> that are *relevant* for itself (e.g. instances of the argument container
>> `ThreedotsForFoo`), that it handles them in a proper way (i.e. extracting
>> the *actual* arguments from the container) and that it passes `...` along
>> to subsequently called functions.
>>
>> That's why I would need methods that use mix of regular formal arguments
>> and `...`.
>>
>> Best regards,
>> Janko
>>
>>
>> On Thu, Nov 27, 2014 at 7:48 PM, Gabriel Becker <gmbecker at ucdavis.edu>
>> wrote:
>>
>>> Janko,
>>>
>>> I'm not entirely sure I understand your proposal. Are you suggesting
>>> methods be dispatched based on the *contents* of ... (ie which arguments
>>> are in there)? This seems like it would be pretty different from how
>>> dispatch behaves now, which is entirely class based.
>>>
>>> Even the dispatching based on ... via dots methods is class based,
>>> having nothing to do AFAIK with the argument names. From ?dotsMethods
>>>
>>> A method selecting on “...” is specified by a single class in the call
>>> to setMethod <http://127.0.0.1:11942/library/methods/help/setMethod>.
>>> If all the actual arguments corresponding to “...” have this class, the
>>> corresponding method is selected directly.
>>>
>>> Otherwise, the class of each argument and that class' superclasses are
>>> computed, beginning with the first “...” argument. For the first argument,
>>> eligible methods are those for any of the classes. For each succeeding
>>> argument that introduces a class not considered previously, the eligible
>>> methods are further restricted to those matching the argument's class or
>>> superclasses. If no further eligible classes exist, the iteration breaks
>>> out and the default method, if any, is selected.
>>>
>>>
>>> No mention of argument name there.
>>>
>>> ~G
>>>
>>> On Thu, Nov 27, 2014 at 9:45 AM, Janko Thyson <janko.thyson at gmail.com>
>>> wrote:
>>>
>>>> Dear List,
>>>>
>>>> I'm currently investigating if the argument dispatch mechanism based on
>>>> `...` could somehow be "generalized" to scenarios that involve `r`
>>>> recipients located across `c` calling stack layers *and* combined with
>>>> the
>>>> S4 method mechanism (for those interested see
>>>>
>>>> http://stackoverflow.com/questions/26963900/generalizing-three-dots-argument-dispatch-s4-methods-for-argument-set-i
>>>> for an (conceptual) approach of how this could be realized).
>>>>
>>>> AFAICT, this would require that `...` can be *mixed* with other
>>>> signature
>>>> arguments, which is currently not supported as stated in `?dotsMethods`:
>>>>
>>>> Quote {
>>>> Using "..." in a Signature
>>>>
>>>> Beginning with version 2.8.0 of R, S4 methods can be dispatched
>>>> (selected
>>>> and called) corresponding to the special argument “...”. Currently,
>>>> “...”
>>>> cannot be mixed with other formal arguments: either the signature of the
>>>> generic function is “...” only, or it does not contain “...”. (This
>>>> restriction may be lifted in a future version.)
>>>> }
>>>>
>>>> Would it be possible to consider lifting this limitation soon?
>>>>
>>>> Thanks a lot to everyone maintaining R!!
>>>>
>>>> Janko
>>>>
>>>> [[alternative HTML version deleted]]
>>>>
>>>> ______________________________________________
>>>> R-devel at r-project.org mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>
>>>
>>>
>>>
>>> --
>>> Gabriel Becker
>>> Graduate Student
>>> Statistics Department
>>> University of California, Davis
>>>
>>
>>
>
>
> --
> Gabriel Becker
> Graduate Student
> Statistics Department
> University of California, Davis
>
[[alternative HTML version deleted]]
More information about the R-devel
mailing list