[Rd] Feature request: mixing `...` (three dots) with other formal arguments in S4 methods

Michael Lawrence lawrence.michael at gene.com
Mon Dec 1 20:52:00 CET 2014


On Thu, Nov 27, 2014 at 6:53 PM, Janko Thyson <janko.thyson at gmail.com>
wrote:

> 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` :-)
>

It would be good to have a solid use case described.  In cases where there
are explicit arguments that need to be in the signature, the `...`
typically forwards extraneous parameters of various types. It seems that
whenever we need to dispatch on `...`, we do not need to dispatch on any
other argument. Collection constructors/combiners are the typical example.


> 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]]
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

	[[alternative HTML version deleted]]



More information about the R-devel mailing list