[R-pkg-devel] Handling Not-Always-Needed Dependencies?

Uwe Ligges ligges at statistik.tu-dortmund.de
Wed Aug 3 15:54:39 CEST 2016



On 03.08.2016 15:20, Thomas J. Leeper wrote:
> The issue seems to boil down to the fact that Suggests is covering two
> very different use cases: (a) conditional package code and (b)
> example/test/vignette code.
>
> Consider a package (say "foo") that is only used in tests. Users do
> not need "foo" since package code never calls it. If our package
> instead calls "foo" conditionally (requireNamespace(); foo::bar(),
> etc.), then users may very well want "foo" and need it much more than
> they would if "foo" were only used in tests. Yet DESCRIPTION does not
> allow a distinction two be made between these two scenarios.
>
> I think the length and complexity of the discussion in WRE[1] makes
> clear that Suggests is being used two cover these two very different
> use cases.


I am more worried about yet another dependency level that confuses more 
than it helps for the majority of developers and users.
As an example, I nneed to explain myself again and again what "Enhances" 
means (and perhaps I am still doing it wrong).

Best,
Uwe Ligges


> -Thomas
>
> [1] https://cran.r-project.org/doc/manuals/r-devel/R-exts.html#Package-Dependencies
>
> Thomas J. Leeper
> http://www.thomasleeper.com
>
>
> On Wed, Aug 3, 2016 at 2:04 PM, Mark van der Loo
> <mark.vanderloo at gmail.com> wrote:
>>>> Recommends: only gets installed, can be used via if(requireNamespace())
>>>> from the package and in pkg tests[1] [snip]
>>>> Build-Depends: gets installed before build, removed after.
>>>> Suggests: only installed when requested at install.packages() and only
>>>> used in examples/vignettes.
>>
>> [snip]
>>>  I'd much rather
>>> have a way of declaring explicitly the different aspects of dependence
>>> on a package rather than bundling them up into cute labels,
>>
>> Agreed
>>
>>> but it's too late for that now.  However, we don't need to make things
>>> worse.
>>
>> Disagreed. We could follow the well-established practices of Debian (and
>> CRAN already does that, partially).
>>
>>
>>>> If 'tons of packages' are using if(requireNamespace) in their package
>>>> code there seems to be a need for something like this. [snip]
>>
>>> I don't follow the argument here.  What problem are you solving?
>>
>> Basically I'm trying to address the idea suggested by Thomas, who started
>> this conversation, and make it a bit more explicit. I felt that the
>> discussion went a little off-track there.
>>
>> Right now, when package code (not examples) uses a suggested package, part
>> of that package will by default not work - at least that's how people use it
>> now. I would like it to work by default. For examples/vignettes you could be
>> more forgiving since running an example is not core functionality of a
>> package.
>>
>>>> Perhaps more controversially a 'Breaks' field could be considered. [snip]
>>
>>> This isn't controversial, it's just a bad idea.  Don't encourage people
>>> to break things.
>>
>> Your reaction just proved my point about it being controversial. More
>> seriously, real progress is hardly ever possible without breaking things, so
>> I think at least people could have a serious discussion about it before
>> dismissing it simply as a bad idea. The Debian community obviously once
>> thought it was a good idea, so why not discuss it for R/CRAN? (discussions
>> are also an important way to progress even if no line of code is changed).
>> At the moment, I'm inclined against the idea, but I for one like to see me
>> proven wrong.
>>
>>
>>>> [1] actually, once we know a pkg is Recommended, the
>>>> 'if(requireNamespace)' could even be absorbed in the :: operator.
>>
>>> I don't see how :: would be any different than it is now.  If you don't
>>> have foo available, and you try to use foo::bar(), what would happen
>>> other than an error?
>>
>> I think you're right there. <resets brain>.
>>
>> Best,
>> Mark
>>
>>
>> Op wo 3 aug. 2016 om 13:41 schreef Duncan Murdoch
>> <murdoch.duncan at gmail.com>:
>>>
>>> On 03/08/2016 5:32 AM, Mark van der Loo wrote:
>>>>
>>>> After reading the link in Dirk's initial reply, how about adding fields
>>>> 'Recommends' and 'Build-Depends' to DESCRIPTION as in Debian?
>>>>
>>>> Recommends: only gets installed, can be used via if(requireNamespace())
>>>> from the package and in pkg tests[1]. [Debian: The Recommends field
>>>> should list packages that would be found together with this one in all
>>>> but unusual installations.]
>>>> Build-Depends: gets installed before build, removed after.
>>>> Suggests: only installed when requested at install.packages() and only
>>>> used in examples/vignettes.
>>>
>>> I think the distinction between Recommends and Suggests is too subtle
>>> here.  I already think it's a bad thing that we are using these words in
>>> ways that don't really correspond to English usage.  I'd much rather
>>> have a way of declaring explicitly the different aspects of dependence
>>> on a package rather than bundling them up into cute labels, but it's too
>>> late for that now.  However, we don't need to make things worse.
>>>
>>>>
>>>> If 'tons of packages' are using if(requireNamespace) in their package
>>>> code there seems to be a need for something like this. Compliance to the
>>>> above can be checked automatically and  a gradual implementation via
>>>> NOTE->WARNING->ERROR in R CMD check seems possible.
>>>
>>> I don't follow the argument here.  What problem are you solving?
>>>
>>>> Perhaps more controversially a 'Breaks' field could be considered. There
>>>> are a few packages out there that have many, many, dependencies.
>>>> Implementing breaking updates currently depends on the willingness of
>>>> many authors to update their package or convincing the CRAN maintainers
>>>> to allow for (temporary) breakage.
>>>
>>> This isn't controversial, it's just a bad idea.  Don't encourage people
>>> to break things.
>>>
>>>> The suggestion to have functions auto-install things is very
>>>> inconvenient for the good reasons pointed out by Thomas. Additionally,
>>>> it is often based on the wrong assumptions. Example: the RGtk2 package
>>>> has this habit of trying to install when libgtk2 is not on the path. But
>>>> in my case that is often exactly the case: it is just not on the path
>>>> (libgtk2 is on the network, the VM just doesn't know yet). So I'd rather
>>>> have a proper and accurate error message (which is good practice
>>>> anyway).
>>>>
>>>>
>>>> Best,
>>>> Mark
>>>>
>>>> [1] actually, once we know a pkg is Recommended, the
>>>> 'if(requireNamespace)' could even be absorbed in the :: operator.
>>>
>>> I don't see how :: would be any different than it is now.  If you don't
>>> have foo available, and you try to use foo::bar(), what would happen
>>> other than an error?
>>>
>>> Duncan Murdoch
>>>
>>>>
>>>>
>>>>
>>>>
>>>> Op wo 3 aug. 2016 om 01:46 schreef Duncan Murdoch
>>>> <murdoch.duncan at gmail.com <mailto:murdoch.duncan at gmail.com>>:
>>>>
>>>>     On 02/08/2016 6:34 PM, Dirk Eddelbuettel wrote:
>>>>     >
>>>>     > On 2 August 2016 at 18:13, Duncan Murdoch wrote:
>>>>     > | Okay, now I think I understand, but I agree with CRAN.  It is
>>>> not
>>>>     > | feasible to tell if the test happened somewhere in the code
>>>>     unless we
>>>>     > | enforce a particular way of writing the test.
>>>>     >
>>>>     > Debian has well over 20k packages, and they are tested this way.
>>>>     You just
>>>>     > need to show the will of testing in an _empty_ environment to
>>>> ensure
>>>>     > _everything_ that is needed is loaded.
>>>>     >
>>>>     > | I would object if I had to write if (requireNamespace("foo"))
>>>>     multiple
>>>>     > | times just to satisfy CRAN's test, when any sane human could
>>>>     tell that
>>>>     > | the first test was sufficient.
>>>>     > |
>>>>     > | For example, if my package Suggests: foo, I should be able to
>>>> write
>>>>     > |
>>>>     > | if (!requireNamespace("foo"))
>>>>     > |    stop("Package foo is needed for this example")
>>>>     > |
>>>>     > | and then merrily call foo::bar() as many times as I like.
>>>>     > |
>>>>     > | Or am I still misunderstanding you?  What particular thing
>>>>     should CRAN
>>>>     > | change?
>>>>     >
>>>>     > You seem to misunderstand that both you and I want
>>>>     >
>>>>     >   if (!requireNamespace("foo"))
>>>>     >      stop("Package foo is needed for this example")
>>>>     >
>>>>     > (or alternative per-call tests) and that CRAN does not enforce
>>>> either.
>>>>     >
>>>>     > CRAN, like Hadley, just closes its eyes, swallows hard, and then
>>>>     simply loads
>>>>     > everything treating Suggests as if it were Depends.
>>>>     >
>>>>     > But it ain't. Suggests != Depends.
>>>>     >
>>>>     > Now clearer?
>>>>
>>>>
>>>>     So really what you're suggesting is that CRAN should run tests with
>>>> the
>>>>     suggested packages absent.  Presumably tests should also be run with
>>>>     them present.
>>>>
>>>>     But if they did that, the code that I want to write would call
>>>> stop()
>>>>     and fail.  So we'd need some way to say "Let the user know they need
>>>>     'foo' to run this, but don't fail."  And we'd need to phase this in
>>>>     really gradually, because tons of packages are using code like my
>>>>     example.
>>>>
>>>>     You volunteered to help CRAN package checking.  Why not put together
>>>>     code to implement your idea, and see how big the problem would be to
>>>>     phase it in, by seeing how many packages fail under it?
>>>>
>>>>     Duncan Murdoch
>>>>
>>>>     ______________________________________________
>>>>     R-package-devel at r-project.org <mailto:R-package-devel at r-project.org>
>>>>     mailing list
>>>>     https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>>>
>>>
>>
>
> ______________________________________________
> R-package-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>



More information about the R-package-devel mailing list