From hpages at fhcrc.org  Fri May 30 21:05:32 2014
From: hpages at fhcrc.org (=?UTF-8?B?SGVydsOpIFBhZ8Oocw==?=)
Date: Fri, 30 May 2014 12:05:32 -0700
Subject: [Rd] Style question
In-Reply-To: <CABdHhvE41f+cpngPjvXtCpbDiy68zBK-Qq-rQXt7c4ueW9FF=Q@mail.gmail.com>
References: <CAOVYLHcgBqBmFMhSnx3hRELV4D9ijdHRoG=SmnRx8g=6f90F3A@mail.gmail.com>
	<538654A4.60402@fhcrc.org>
	<CABdHhvHP7VRmU6Z68EDieEPOsyqUkFRrkuG=ohO0f8V5J0tWUw@mail.gmail.com>
	<5388B803.8030506@fhcrc.org>
	<CABdHhvE41f+cpngPjvXtCpbDiy68zBK-Qq-rQXt7c4ueW9FF=Q@mail.gmail.com>
Message-ID: <5388D67C.7010807@fhcrc.org>

On 05/30/2014 10:00 AM, Hadley Wickham wrote:
>> There is at least one subtle consequence to keep in mind when doing
>> this. Of course, whatever choice you make, if the whatever() function
>> moves to a different package, this breaks your package.
>> However, if you explicitly import the function, your package will
>> break at load-time (which is good) and you'll only have to modify
>> 1 line in the NAMESPACE file to fix it. But if you do foo::whatever(),
>> your package won't break at load-time, only at run-time. Also you'll
>> have to edit all the calls to foo::whatever() to fix the package.
>>
>> Probably not a big deal, but in an environment like Bioconductor where
>> infrastructure classes and functions can be shared by hundreds of
>> packages, having people use foo::whatever() in a systematic way would
>> probably make maintenance a little bit more painful than it needs to
>> be when the need arises to reorganize/refactor parts of the
>> infrastructure. Also, the ability to quickly grep the NAMESPACE
>> files of all BioC packages to see who imports what is very convenient
>> in this situation.
>
> OTOH, I think there's a big benefit to being able to read package code
> and instantly know where a function comes from.

To me this is way more readable:

   setClass("A", representation(...))
   setMethod("head", "A", function(x, ...) {...})

than this:

   methods::setClass("A", methods::representation(...))
   methods::setMethod(utils::head, "A", function(x, ...) {...})

All the :: clutter adds very little value and hurts readability.
Just a matter of taste I guess.

Also it almost never matters to me *where* a function comes from.
The only thing I find relevant when I read code is *what* a function
does and I can find out by doing ?whatever (I generally don't need
to do ?foo::whatever). If I need to try it (interactively), I do
whatever(...), not foo::whatever(...). Sometimes, ?whatever will
fail because foo's NAMESPACE is loaded but foo is not attached to my
search path. In that case, and in that case only, I need to know
*where* the function comes from so I can library() the package where
it's defined and documented, and then I can do ?whatever. But this is
a rare situation and doesn't justify systematic use of foo::whatever().

So I only reserve the use of foo::whatever() to disambiguate in case
of name collision or to call a function defined in a *suggested*
package.

Finally, now that the use of a NAMESPACE became mandatory (well, this
happened a few years ago), advocating systematic use of foo::whatever()
without explicitly importing the function sounds a little bit like an
heroic act of resistance ;-)

H.

>
> Personally, I found this outweighs the benefits that you outline:
>
> * functions rarely move between packages, and gsubbing for pkga:foo to
> pkgb:foo isn't hard
> * it's not that much hard to grep for pkg::foo in R/* than it is to
> grep NAMESPACE
>
> Hadley
>

-- 
Herv? Pag?s

Program in Computational Biology
Division of Public Health Sciences
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N, M1-B514
P.O. Box 19024
Seattle, WA 98109-1024

E-mail: hpages at fhcrc.org
Phone:  (206) 667-5791
Fax:    (206) 667-1319



[Rd] Style question
=?UTF-8?B?SGVydsOpIFBhZ8Oocw==?=