From murdoch.duncan at gmail.com  Thu Apr 12 20:14:02 2012
From: murdoch.duncan at gmail.com (Duncan Murdoch)
Date: Thu, 12 Apr 2012 14:14:02 -0400
Subject: [Rd] [patch] giving library() a 'version' argument
In-Reply-To: <21A5E1E970CD46459ECBE86D6CC4B28C667AAA5D@spexch01.WindLogics.local>
References: <21A5E1E970CD46459ECBE86D6CC4B28C667AA79C@spexch01.WindLogics.local>
	<4F86C8DC.7020608@gmail.com>
	<21A5E1E970CD46459ECBE86D6CC4B28C667AA9BA@spexch01.WindLogics.local>
	<4F87106D.9050402@gmail.com>
	<21A5E1E970CD46459ECBE86D6CC4B28C667AAA5D@spexch01.WindLogics.local>
Message-ID: <4F871B6A.8010000@gmail.com>

On 12/04/2012 1:46 PM, Ken Williams wrote:
>
> >  -----Original Message-----
> >  From: Duncan Murdoch [mailto:murdoch.duncan at gmail.com]
> >  Sent: Thursday, April 12, 2012 12:27 PM
> >  To: Ken Williams
> >  Cc: r-devel at r-project.org
> >  Subject: Re: [Rd] [patch] giving library() a 'version' argument
> >
> >  I haven't tested it, but according to the documentation in Writing R
> >  Extensions, the dependencies are enforced at the time library() is called.
>
> Oh, I hadn't suspected that.  I can look into testing that, if it's true then of course that changes this all.  I probably won't be able to do that for a few days because I'll be traveling though.
>
> I've never noticed a package failing to load at runtime because its prereq-version dependency wasn't met though.
>
> >  [...]
> >  But a single line at the top of the script would fix this:
> >
> >  stopifnot(packageVersion("foo") == "3.14")
>
> For the most common use case, that would look more like:
>
>      stopifnot(compareVersion(packageVersion("foo"), "3.14")<  0)

The compareVersion call doesn't need to be explicit, i.e. you'll get the 
same result from

stopifnot(packageVersion("foo")<  "3.14")


which looks pretty clear to me.  It works in some quick tests, 
recognizing that rgl version 0.92.879 is bigger than 0.92.100 but less 
than 0.92.1000.

Duncan Murdoch

>
> which gets less declarative, and I'd argue less clear about exactly what it's trying to enforce.
>
> And I can see myself (&  presumably others) getting that comparison operator backwards a lot, having to look it up each time or copy-paste it from other code.
>
> And then that still doesn't add nice error messages, that would be yet more code.
>
> *And*, it doesn't actually behave correctly if the package is already loaded by other code, because it might have been loaded from a different location than the one that would be found in the packageVersion() call.  (Or am I maybe wrong about what packageVersion() does in that case?  I don't think the docs specify that behavior.)
>
>
> For prior art on this whole concept, a useful precedent is the 'use()' function in Perl, which accepts a version argument, even though there is also robust version checking at installation/testing time.
>
> >
> >  Another problem with putting this into library() is that packages aren't
> >  always loaded by library():  there is require(), and there are implicit
> >  loads triggered by dependencies of other packages.
>
> That's not really a problem.  If someone wants to enforce a runtime dependency, they stick the enforcement line into their code, and it will correctly stop if the criterion is not met.
>
>   -Ken
>
> CONFIDENTIALITY NOTICE: This e-mail message is for the sole use of the intended recipient(s) and may contain confidential and privileged information. Any unauthorized review, use, disclosure or distribution of any kind is strictly prohibited. If you are not the intended recipient, please contact the sender via reply e-mail and destroy all copies of the original message. Thank you.



[Rd] [patch] giving library() a 'version' argument
Duncan Murdoch