11# ' Find the prototype of a set of vectors
22# '
3- # ' `vec_ptype()` returns the unfinalised prototype of a single vector.
4- # ' `vec_ptype_common()` finds the common type of multiple vectors.
5- # ' `vec_ptype_show()` nicely prints the common type of any number of
6- # ' inputs, and is designed for interactive exploration.
3+ # ' @description
4+ # ' - `vec_ptype()` returns the [unfinalised][vec_ptype_finalise] prototype of a
5+ # ' single vector.
6+ # '
7+ # ' - `vec_ptype_common()` returns the common type of multiple vectors. By
8+ # ' default, this is [finalised][vec_ptype_finalise] for immediate usage, but
9+ # ' can optionally be left unfinalised for advanced common type determination.
10+ # '
11+ # ' - `vec_ptype_show()` nicely prints the common type of any number of inputs,
12+ # ' and is designed for interactive exploration.
713# '
814# ' @inheritParams rlang::args_error_context
915# '
1016# ' @param x A vector
17+ # '
1118# ' @param ... For `vec_ptype()`, these dots are for future extensions and must
1219# ' be empty.
1320# '
1421# ' For `vec_ptype_common()` and `vec_ptype_show()`, vector inputs.
22+ # '
1523# ' @param x_arg Argument name for `x`. This is used in error messages to inform
1624# ' the user about the locations of incompatible types.
25+ # '
1726# ' @param .ptype If `NULL`, the default, the output type is determined by
1827# ' computing the common type across all elements of `...`.
1928# '
2029# ' Alternatively, you can supply `.ptype` to give the output known type.
2130# ' If `getOption("vctrs.no_guessing")` is `TRUE` you must supply this value:
2231# ' this is a convenient way to make production code demand fixed types.
32+ # '
33+ # ' @param .finalise Should `vec_ptype_common()` [finalise][vec_ptype_finalise]
34+ # ' its output?
35+ # '
36+ # ' - If `TRUE`, [vec_ptype_finalise()] is called on the final `ptype` before
37+ # ' it is returned. Practically this has the effect of converting any
38+ # ' types from [unspecified] to logical.
39+ # '
40+ # ' - If `FALSE`, [unspecified] types are left unfinalised, which can be useful
41+ # ' for advanced cases where you combine one common type result with another
42+ # ' type via [vec_ptype2()]. Note that you must manually call
43+ # ' [vec_ptype_finalise()] on the final `ptype` before supplying it to any
44+ # ' other vctrs functions.
45+ # '
2346# ' @return `vec_ptype()` and `vec_ptype_common()` return a prototype
24- # ' (a size-0 vector)
47+ # ' (a size-0 vector).
2548# '
2649# ' @section `vec_ptype()`:
50+ # '
2751# ' `vec_ptype()` returns [size][vec_size] 0 vectors potentially
2852# ' containing attributes but no data. Generally, this is just
2953# ' `vec_slice(x, 0L)`, but some inputs require special
3660# ' * The prototype of logical vectors that only contain missing values
3761# ' is the special [unspecified] type, which can be coerced to any
3862# ' other 1d type. This allows bare `NA`s to represent missing values
39- # ' for any 1d vector type.
63+ # ' for any 1d vector type. [Finalising][vec_ptype_finalise] this type
64+ # ' converts it from unspecified back to logical.
4065# '
4166# ' See [internal-faq-ptype2-identity] for more information about
4267# ' identity values.
4974# ' improve the performance of your class in many cases ([common
5075# ' type][vec_ptype2] imputation in particular).
5176# '
52- # ' Because it may contain unspecified vectors, the prototype returned
53- # ' by `vec_ptype()` is said to be __unfinalised__. Call
54- # ' [vec_ptype_finalise()] to finalise it. Commonly you will need the
55- # ' finalised prototype as returned by `vec_slice(x, 0L)`.
77+ # ' Because it may contain unspecified vectors, the prototype returned by
78+ # ' `vec_ptype()` is said to be __unfinalised__. Call [vec_ptype_finalise()] to
79+ # ' finalise it.
5680# '
5781# ' @section `vec_ptype_common()`:
82+ # '
5883# ' `vec_ptype_common()` first finds the prototype of each input, then
59- # ' successively calls [vec_ptype2()] to find a common type. It returns
60- # ' a [finalised][vec_ptype_finalise] prototype.
84+ # ' successively calls [vec_ptype2()] to find a common type. It returns a
85+ # ' [finalised][vec_ptype_finalise] prototype by default, but can optionally be
86+ # ' left unfinalised for advanced common type determination.
6187# '
6288# ' @section Dependencies of `vec_ptype()`:
6389# ' - [vec_slice()] for returning an empty slice
7096# ' @examples
7197# ' # Unknown types ------------------------------------------
7298# ' vec_ptype_show()
73- # ' vec_ptype_show(NA)
7499# ' vec_ptype_show(NULL)
75100# '
76101# ' # Vectors ------------------------------------------------
100125# ' data.frame(y = 2),
101126# ' data.frame(z = "a")
102127# ' )
128+ # '
129+ # ' # Finalisation -------------------------------------------
130+ # '
131+ # ' # `vec_ptype()` and `vec_ptype2()` return unfinalised ptypes so that they
132+ # ' # can be coerced to any other type
133+ # ' vec_ptype(NA)
134+ # ' vec_ptype2(NA, NA)
135+ # '
136+ # ' # By default `vec_ptype_common()` finalises so that you can use its result
137+ # ' # directly in other vctrs functions
138+ # ' vec_ptype_common(NA, NA)
139+ # '
140+ # ' # You can opt out of finalisation to make it work like `vec_ptype()` and
141+ # ' # `vec_ptype2()` with `.finalise = FALSE`, but don't forget that you must
142+ # ' # call `vec_ptype_finalise()` manually if you do so!
143+ # ' vec_ptype_common(NA, NA, .finalise = FALSE)
144+ # ' vec_ptype_finalise(vec_ptype_common(NA, NA, .finalise = FALSE))
145+ # '
146+ # ' # This can be useful in rare scenarios, like including a separate `default`
147+ # ' # argument in the ptype computation
148+ # ' xs <- list(NA, NA)
149+ # ' default <- "a"
150+ # ' try(vec_ptype2(vec_ptype_common(!!!xs), default))
151+ # ' vec_ptype2(vec_ptype_common(!!!xs, .finalise = FALSE), default)
103152vec_ptype <- function (x , ... , x_arg = " " , call = caller_env()) {
104153 check_dots_empty0(... )
105154 return (.Call(ffi_ptype , x , x_arg , environment()))
@@ -111,20 +160,28 @@ vec_ptype <- function(x, ..., x_arg = "", call = caller_env()) {
111160vec_ptype_common <- function (
112161 ... ,
113162 .ptype = NULL ,
163+ .finalise = TRUE ,
114164 .arg = " " ,
115165 .call = caller_env()
116166) {
117- .External2(ffi_ptype_common , list2(... ), .ptype )
167+ .External2(ffi_ptype_common , list2(... ), .ptype , .finalise )
118168}
119169
120170vec_ptype_common_params <- function (
121171 ... ,
122172 .ptype = NULL ,
173+ .finalise = TRUE ,
123174 .fallback_opts = fallback_opts(),
124175 .arg = " " ,
125176 .call = caller_env()
126177) {
127- .External2(ffi_ptype_common_params , list2(... ), .ptype , .fallback_opts )
178+ .External2(
179+ ffi_ptype_common_params ,
180+ list2(... ),
181+ .ptype ,
182+ .finalise ,
183+ .fallback_opts
184+ )
128185}
129186
130187vec_ptype_common_fallback <- function (
0 commit comments