From macrakis at alum.mit.edu  Wed Sep  2 20:39:27 2009
From: macrakis at alum.mit.edu (Stavros Macrakis)
Date: Wed, 2 Sep 2009 14:39:27 -0400
Subject: [Rd] Documentation for is.atomic and is.recursive
Message-ID: <8b356f880909021139pa07d922q1f1c28a0fb70cdbe@mail.gmail.com>

The documentation for is.atomic and is.recursive is inconsistent with
their behavior in R 2.9.1 Windows.

? is.atomic

???? 'is.atomic' returns 'TRUE' if 'x' is an atomic vector (or 'NULL')
???? and 'FALSE' otherwise.
???? ...
???? 'is.atomic' is true for the atomic vector types ('"logical"',
???? '"integer"', '"numeric"', '"complex"', '"character"' and '"raw"')
???? and 'NULL'.

This description implies that is.atomic(x) implies is.vector(x)
(assuming that an "atomic vector type" is a subset of a "vector
type").? But in fact that is not true for values with class
attributes:

is.atomic(factor(3)) => TRUE
is.vector(factor(3)) => FALSE

is.atomic(table(3)) => TRUE
is.vector(factor(3)) => FALSE

It appears, then, that is.atomic requires only that unclass(x) be an
atomic vector, not that x be an atomic vector.

There is also another case where is.atomic(x) != is.vector(unclass(x)):

is.atomic(NULL) => TRUE
is.vector(NULL) => FALSE

It would be useful to make the documentation consistent with the
implementation. (Presumably by updating the documentation, not
changing the behavior.)

The documentation continues:

???? 'is.recursive' returns 'TRUE' if 'x' has a recursive (list-like)
???? structure and 'FALSE' otherwise.
???? ...
???? Most types of language objects are regarded as recursive: those
???? which are not are the atomic vector types, 'NULL' and symbols (as
???? given by 'as.name').

But is.recursive(as.name('foo')) == is.recursive(quote(foo)) == FALSE.

Again, it would be useful to make the documentation consistent with
the implementation.

To summarize all this in a table of the most common datatypes:

outerl <-
? function(f, a, b)
??? structure(outer(a,b,Vectorize(f)),
????????????? dimnames=list(a,b))

outerl(function(x,f)(match.fun(f))(x),
?????? list(3,factor(c("a","b")),NULL,function()3,as.name("foo"),environment()),
?????? list("class","mode","storage.mode","is.vector","is.atomic","is.recursive"))

????????????? class???????? mode????????? storage.mode? is.vector
is.atomic is.recursive
3???????????? "numeric"???? "numeric"???? "double"????? "TRUE"
"TRUE"??? "FALSE"????       <<< OK
1:2?????????? "factor"????? "numeric"???? "integer"???? "FALSE"
"TRUE"??? "FALSE"????         <<< inconsistent
NULL????????? "NULL"??????? "NULL"??????? "NULL"??????? "FALSE"
"TRUE"??? "FALSE"????     <<< inconsistent
function ()?? "function"??? "function"??? "function"??? "FALSE"
"FALSE"?? "TRUE"?????     <<< OK
foo?????????? "name"??????? "name"??????? "symbol"????? "FALSE"
"FALSE"?? "FALSE"????      <<< inconsistent
<environment> "environment" "environment" "environment" "FALSE"
"FALSE"?? "TRUE"?????<<< OK

Thanks,

           -s



[Rd] Documentation for is.atomic and is.recursive
Stavros Macrakis