[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 16:53:12 CEST 2024
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.
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