From macrakis at alum.mit.edu  Wed Sep  2 22:10:08 2009
From: macrakis at alum.mit.edu (Stavros Macrakis)
Date: Wed, 2 Sep 2009 16:10:08 -0400
Subject: [Rd] Documentation for is.atomic and is.recursive
In-Reply-To: <4A9EC967.3080507@stats.uwo.ca>
References: <8b356f880909021139pa07d922q1f1c28a0fb70cdbe@mail.gmail.com>
	<4A9EC967.3080507@stats.uwo.ca>
Message-ID: <8b356f880909021310l3805de62g2c2467db9a1591d2@mail.gmail.com>

Let us stipulate that the current wording can be construed to be correct.

I would nonetheless claim that the documentation as currently written
is at best ambiguous and confusing, and would benefit from improved
wording.

What would be lost by that?

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

I explicitly said in my mail that I was not suggesting that past
design decisions (wise or unwise) be revisited; only that they be
documented more clearly.

               -s

On Wed, Sep 2, 2009 at 3:37 PM, Duncan Murdoch<murdoch at stats.uwo.ca> wrote:
> 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
Stavros Macrakis