From murdoch at stats.uwo.ca  Wed Sep  2 21:37:11 2009
From: murdoch at stats.uwo.ca (Duncan Murdoch)
Date: Wed, 02 Sep 2009 15:37:11 -0400
Subject: [Rd] Documentation for is.atomic and is.recursive
In-Reply-To: <8b356f880909021139pa07d922q1f1c28a0fb70cdbe@mail.gmail.com>
References: <8b356f880909021139pa07d922q1f1c28a0fb70cdbe@mail.gmail.com>
Message-ID: <4A9EC967.3080507@stats.uwo.ca>

On 9/2/2009 2:39 PM, Stavros Macrakis wrote:
> 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:

I don't see is.vector mentioned there.  The description of is.vector on 
its own man page implies the behaviour below; I think the description of 
is.atomic that you quote above is also consistent with the behaviour.

One could argue that in R's pre-history we should have had is.atomic 
imply is.vector, but that's not how things are documented, and I think 
we're pretty much stuck with the definitions we've got on low level 
functions like those.


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

That's what it says should happen.  symbols such as as.name('foo') are 
not recursive.

Duncan Murdoch

> 
> 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
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] Documentation for is.atomic and is.recursive
Duncan Murdoch