[Rd] legitimate use of :::

Duncan Murdoch murdoch.duncan at gmail.com
Mon Aug 26 20:24:15 CEST 2013

On 26/08/2013 11:20 AM, Benjamin Hofner wrote:
> Dear Duncan,
> thank you for the quick reply.
> Am 26.08.2013 16:47, schrieb Duncan Murdoch:
> > On 26/08/2013 8:51 AM, Benjamin Hofner wrote:
> >> Hi,
> >>
> >> related to this important discussion I have several questions:
> >>
> >> What can I do to explicitly state that I want to use a certain,
> >> *non-exported* generic function? The function I am currently talking of
> >> is predict.smooth.spline from package stats. As I want to make shure
> >> that *this* function is used I currently call
> >> stats:::predict.smooth.spline() in my code, which now triggers a NOTE on
> >> CRAN. Strange enough predict.smooth.spline even has a manual page but is
> >> not exported (as is true for many other generic functions as well).
> >
> > Actually the standard name is that predict() is a generic function,
> > predict.smooth.spline() is a method, but it's a good question.  Can you
> > describe why you want to call that method on something that isn't a
> > smooth.spline object?
> Actually the object is a smooth.spline object but with additional
> attributes and more classes, i.e.,
> class(mod)
> [1] "opm_model"           "smooth.spline_model" "smooth.spline"
> Now I have a specialized predict function predict.smooth.spline_model
> which in turn calls predict.smooth.spline.
> I just tried to use NextMethod(generic = "predict", object, ...) and it
> seems to work. So this seems to be the desired solution. I tried this
> earlier and got error messages, perhaps because I omitted the argument
> generic. I guess the function then was confused what the generic is
> (predict or predict.smooth).
> >>
> >> Is it advisable to specify (S3) methods without exporting them? How can
> >> I access exactly this function without using :::? And/or shouldn't we (R
> >> Core in this instance but others - including myself) export all methods
> >> (especially if a manual exists anyway)?
> >
> > The general reason for hiding methods is that it allows the author of
> > the package to change the internal implementation of the class without
> > worrying that it will break code that uses the method, i.e. it will stop
> > usages such as yours.  So you need to explain why you are doing what you
> > are doing.
> I see no difference in these two ways to call the next generic function:
> In both cases I can (and do) specify further arguments, namely x for new
> data and deriv = 0. Thus in both cases I rely on the interface in the
> same way. I do not see any bonus for the package maintainer (both of the
> depending and dependent package). The interface stays the same and the
> class could change in both situations. Isn't a method always relying on
> the current implementation of a class? And isn't anything else more than
> unwanted? So again? Why hiding a method? The only reason I see is that
> one doesn't want to document the function properly.

But as you've discovered, you don't need ::: access, you can use 
NextMethod.  You would need ::: access if the object wasn't a 
smooth.spline object, because then the generic and NextMethod wouldn't 
dispatch to the method.  If you were calling a smooth.spline method on 
something that is not a smooth.spline object, your code could break if 
something about the  smooth.spline class was changed, and the predict 
method for it was adjusted to compensate.
> >
> >
> >> A related question concerns the function stats:::n.knots. I want to use
> >> this function to compute the number of knots for a spline (not
> >> necessarily a smoothing spline as defined by smooth.spline were it is
> >> originally used). The source of the function even states as a comment:
> >> "## Namespace-hidden but at least available to programmeRs:" So I guess
> >> this function can be considered to be stable and usable. Would it then
> >> be possible for R Core to export this function?
> Do I need to file a formal request for this issue?

It might be better to write to the author of that comment.  You can find 
out who that is using "svn blame" (or as some of us prefer, "svn 
praise") on the file.

> >> Finally, if one needs to copy a function (perhaps with minor
> >> modifications), how does one properly state the authorship of the code
> >> that one copies? Are there any guidelines, rules, ...? Is it sufficient
> >> for small functions to state the original authorship as a comment in the
> >> source? Is it necessary to state the authorship in the manual? Or is it
> >> even required to state the quthorship in the DESCRITPION? I already did
> >> an extensive search of the R-devel mailing list but couldn't find an
> >> appropriate answer. And after all I do not want to spend hours and hours
> >> thinking about licenses, authorship etc. but I want to produce nice and
> >> usable code (but also want to mention the original authors
> >> appropriately)!
> >
> > I would say that you should certainly state it in the man page, and have
> > something in the DESCRIPTION file as well.  It might be something like
> >
> > Author:  Duncan Murdoch, with code from others (see the man pages)
> >
> > However, I just looked at rgl (a package I maintain), and I see we
> > didn't do that.  We have a separate README file listing other credits.
> This is a good solution. Do I need to specify the original License etc?
> And what about a helper function such as stats:::n.knots? This will not
> appear in the manual of my package. Is it sufficient in this case to
> document the authorship in the source (and perhaps a README as you
> suggested)?
I think you want to give credit in a place where users will see it, not 
just in the source.  Our README solution isn't good for that, because 
most people will never know they have that file.

Duncan Murdoch

More information about the R-devel mailing list