From Ken.Williams at windlogics.com  Thu Apr 12 19:46:33 2012
From: Ken.Williams at windlogics.com (Ken Williams)
Date: Thu, 12 Apr 2012 12:46:33 -0500
Subject: [Rd] [patch] giving library() a 'version' argument
In-Reply-To: <4F87106D.9050402@gmail.com>
References: <21A5E1E970CD46459ECBE86D6CC4B28C667AA79C@spexch01.WindLogics.local>
	<4F86C8DC.7020608@gmail.com>
	<21A5E1E970CD46459ECBE86D6CC4B28C667AA9BA@spexch01.WindLogics.local>
	<4F87106D.9050402@gmail.com>
Message-ID: <21A5E1E970CD46459ECBE86D6CC4B28C667AAA5D@spexch01.WindLogics.local>



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

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 s...{{dropped:7}}



[Rd] [patch] giving library() a 'version' argument
Ken Williams