[Rd] Signature of '!' (was Problem with R-2.5.0 patched and Matrix package)

Prof Brian Ripley ripley at stats.ox.ac.uk
Thu Apr 26 23:57:11 CEST 2007

Yes, it works in the release.

The essence of the problem is that Matrix defines an S4 method for '!' 
with dispatch on 'e1', but the documentation for '!' (and many S3 methods) 
says the argument is 'x'.  As '!' is a primitive the argument matching of 
the base function might be expected to be positional only, but that is not 
what happens with methods.

This needs some juggling, and clearly two patches in R-patched have 
conflicted.  I've reverted one of them and this seems to work again (but 
something else no longer works: see below).

Longer term, I don't know what the right way forward is.  Consider

> setClass("foo", "logical")
[1] "foo"
> setMethod("!", "foo", function(e1) NA)
[1] "!"
> x <- new("foo", TRUE)
> !x
[1] NA
> `!`(x)
[1] NA
> `!`(x=x)
Error in !x : unused argument(s) (x = TRUE)
> `!`(e1=x)
[1] NA

which is not what the reader of the help for '!' might expect.  But it 
gets worse:

> x2 <- structure(TRUE, class="bar")
> `!.bar` <- function(x) NA
(and there are several S3 methods like that in CRAN packages)
> !x2
[1] NA
> `!`(x2)
[1] NA
> `!`(x=x2)
Error in !x2 : unused argument(s) (x = TRUE)
> `!`(e1=x2)
Error in `!.bar`(e1 = x2) : unused argument(s) (e1 = TRUE)

whereas `!`(x=x2) does work if you do not set an S4 method on '!'.
This may seem artificial, but this sort of thing can happen if you use 
operators as functions in lapply().

Since there are in packages S3 methods on 'x' and S4 methods on 'e1', we 
have a conflict.

My gut feeling is that the inconsistency is the S4 signature, and 
certainly that seems the easier one to change.  I knew about this because 
the behind-the-scenes S4 generics in R-devel are auto-generated from the 
descriptions of the primitives.  Now in 2.5.0 you will see

> `!`
function (x)  .Primitive("!")

and hence there needed to be an exclusion list (which now includes '!' and 
'c')  to have Matrix work in R-devel.  An alternative is to make the 
internal method dispatch on operators ignore the argument names.

(I can guess where this comes from.  '!' is a member of the S3 Ops group, 
and as part of a group method you define Ops(e1, e2) and ignore e2.  But 
'!' is not part of the S4 group generic Logic in R.)

Thanks for the report.

On Thu, 26 Apr 2007, Seth Falcon wrote:

> Hi,
> Using latest R 2.5.0 Patched, I'm unable to install the Matrix package
> from cran.fhcrc.org.
> I get:
> Creating a new generic function for "isSymmetric" in "Matrix"
> Creating a new generic function for "unname" in "Matrix"
> Error in conformMethod(signature, mnames, fnames, f) :
>        In method for function "!": formal arguments omitted in the method definition cannot be in the signature (x = "Matrix")
> Error: unable to load R code in package 'Matrix'
> Execution halted
> ERROR: lazy loading failed for package 'Matrix'
> ** Removing '/home/sfalcon/RLIBS/2.5/Matrix'
> ** Restoring previous '/home/sfalcon/RLIBS/2.5/Matrix'
> The downloaded packages are in
>        /tmp/RtmpcEQJjw/downloaded_packages
> Warning message:
> installation of package 'Matrix' had non-zero exit status in: install.packages(pkgs = pkgs, repos = repos, dependencies = dependencies,
> I don't have this problem when using a recent R-devel.  And I'm
> guessing that Matrix works with the release, but haven't had time to
> check this.
> + seth

Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

More information about the R-devel mailing list