[Rd] Should c(..., recursive = TRUE) and unlist(x, recursive = TRUE) recurse into expression vectors?

Mikael Jagan j@g@nmn2 @end|ng |rom gm@||@com
Sat Apr 27 17:20:51 CEST 2024



On 2024-04-27 10:53 am, Mikael Jagan wrote:
> Reading the body of function 'AnswerType' in bind.c, called from 'do_c'
> and 'do_unlist', I notice that EXPRSXP and VECSXP are handled identically
> in the  recurse = TRUE  case.
> 
> A corollary is that  c(recursive = TRUE)  and  unlist(recursive = TRUE)
> treat expression vectors like  expression(a, b)  as lists of symbols and
> calls.  And since they treat symbols and calls as lists of length 1, we
> see:
> 
>   > x <- expression(a, b); y <- expression(c, d)
>   > c(x, y)
> expression(a, b, c, d)
>   > c(x, y, recursive = TRUE)
> [[1]]
> a
> 
> [[2]]
> b
> 
> [[3]]
> c
> 
> [[4]]
> d
> 
> My expectation based on the documentation in help("c") and help("unlist")
> is that those functions would recurse into lists and pairlists, but _not_
> into expression vectors.
> 
>       recursive: logical.  If 'recursive = TRUE', the function recursively
>                 descends through lists (and pairlists) combining all their
>                 elements into a vector.
> 
>       recursive: logical.  Should unlisting be applied to list components of
>                 'x'?
> 
> My feeling is that either:
> 
> (1) the behaviour should change, so that both calls to 'c' above give
>       the result of type "expression".
> (2) the documentation should change to say that expression vectors are
>       handled as lists in the recursive case.
> 
> Option (2) won't break anything but is a bit awkward because it means
> that a type "higher" in the documented hierarchy (... < list < expression)
> is coerced to a lower type.
> 

Er - this last comment about Option (2) being awkward can be ignored.  The
expression vector is not itself coerced to a list.  Rather, its non-vector
components are treated as lists of length 1.  And that's well-documented.

If anything, Option (1) is awkward as it would treat two types of generic
vectors, list and expression, asymmetrically ...

I can submit a patch implementing Option (2) in a few days to allow for
comments if any.

Mikael

> I'll add here that, confusingly, help("expression") says: "an object of
> mode 'expression' is a list".  I understand the author's intent (lists and
> expression vectors differ only in the 'type' field of the SEXP header) but
> I wonder if substituting "list" with "generic vector" there would cause
> less confusion ... ?
> 
> Mikael



More information about the R-devel mailing list