% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/faq-developer.R
\name{reference-faq-compatibility}
\alias{reference-faq-compatibility}
\title{FAQ - Is my class compatible with vctrs?}
\description{
vctrs provides a framework for working with vector classes in a generic
way. However, it implements several compatibility fallbacks to base R
methods. In this reference you will find how vctrs tries to be
compatible with your vector class, and what base methods you need to
implement for compatibility.

If you’re starting from scratch, we think you’ll find it easier to start
using \code{\link[=new_vctr]{new_vctr()}} as documented in
\code{vignette("s3-vector")}. This guide is aimed for developers with
existing vector classes.
\subsection{Aggregate operations with fallbacks}{

All vctrs operations are based on four primitive generics described in
the next section. However there are many higher level operations. The
most important ones implement fallbacks to base generics for maximum
compatibility with existing classes.
\itemize{
\item \code{\link[=vec_slice]{vec_slice()}} falls back to the base \code{[} generic if no
\code{\link[=vec_proxy]{vec_proxy()}} method is implemented. This way foreign
classes that do not implement \code{\link[=vec_restore]{vec_restore()}} can
restore attributes based on the new subsetted contents.
\item \code{\link[=vec_c]{vec_c()}} and \code{\link[=vec_rbind]{vec_rbind()}} now fall back to
\code{\link[base:c]{base::c()}} if the inputs have a common parent class with
a \code{c()} method (only if they have no self-to-self \code{vec_ptype2()}
method).

vctrs works hard to make your \code{c()} method success in various
situations (with \code{NULL} and \code{NA} inputs, even as first input which
would normally prevent dispatch to your method). The main downside
compared to using vctrs primitives is that you can’t combine vectors
of different classes since there is no extensible mechanism of
coercion in \code{c()}, and it is less efficient in some cases.
}
}

\subsection{The vctrs primitives}{

Most functions in vctrs are aggregate operations: they call other vctrs
functions which themselves call other vctrs functions. The dependencies
of a vctrs functions are listed in the Dependencies section of its
documentation page. Take a look at \code{\link[=vec_count]{vec_count()}} for an
example.

These dependencies form a tree whose leaves are the four vctrs
primitives. Here is the diagram for \code{vec_count()}:

\figure{vec-count-deps.png}
\subsection{The coercion generics}{

The coercion mechanism in vctrs is based on two generics:
\itemize{
\item \code{\link[=vec_ptype2]{vec_ptype2()}}
\item \code{\link[=vec_cast]{vec_cast()}}
}

See the \link[=theory-faq-coercion]{theory overview}.

Two objects with the same class and the same attributes are always
considered compatible by ptype2 and cast. If the attributes or classes
differ, they throw an incompatible type error.

Coercion errors are the main source of incompatibility with vctrs. See
the \link[=howto-faq-coercion]{howto guide} if you need to implement methods
for these generics.
}

\subsection{The proxy and restoration generics}{
\itemize{
\item \code{\link[=vec_proxy]{vec_proxy()}}
\item \code{\link[=vec_restore]{vec_restore()}}
}

These generics are essential for vctrs but mostly optional.
\code{vec_proxy()} defaults to an \link{identity} function and you
normally don’t need to implement it. The proxy a vector must be one of
the atomic vector types, a list, or a data frame. By default, S3 lists
that do not inherit from \code{"list"} do not have an identity proxy. In that
case, you need to explicitly implement \code{vec_proxy()} or make your class
inherit from list.
}

}
}
