Expand description
AltrepSexp — a !Send + !Sync wrapper for ALTREP vectors.
R uses ALTREP (Alternative Representations) for common idioms like 1:N,
seq_len(N), and as.character(1:N). These vectors are lazily materialized:
calling DATAPTR_RO triggers allocation, GC, and C callbacks inside R’s
runtime. This must only happen on the R main thread.
This module provides two complementary tools:
AltrepSexp— a!Send + !Syncwrapper that holds an ALTREP SEXP and prevents it from crossing thread boundaries at compile time.ensure_materialized— a function that forces materialization if the SEXP is ALTREP, returning a SEXP with a stable data pointer.
Plain (non-ALTREP) SEXPs are Send + Sync and are unaffected by either.
§How ALTREP flows through miniextendr
| Parameter type | ALTREP handling |
|---|---|
Typed (Vec<i32>, &[f64]) | Auto-materialized via DATAPTR_RO in TryFromSexp |
SEXP | Auto-materialized via ensure_materialized in TryFromSexp |
AltrepSexp | Wrapped without materializing. !Send + !Sync. |
extern "C-unwind" raw SEXP | No conversion — receives raw SEXP as-is |
§Usage
ⓘ
use miniextendr_api::AltrepSexp;
// As a #[miniextendr] parameter — accepts only ALTREP vectors:
#[miniextendr]
pub fn altrep_length(x: AltrepSexp) -> usize {
x.len()
}
// Manual wrapping:
if let Some(altrep) = AltrepSexp::try_wrap(sexp) {
// Must materialize on R main thread before accessing data
let materialized: SEXP = unsafe { altrep.materialize() };
}
// Or use the convenience helper on any SEXP:
let safe_sexp = unsafe { ensure_materialized(sexp) };See also: docs/ALTREP_SEXP.md for the full guide on receiving ALTREP
vectors from R.
Structs§
- Altrep
Sexp - A SEXP known to be ALTREP.
!Send + !Sync— must be materialized on the R main thread before data can be accessed or sent to other threads.
Functions§
- ensure_
materialized ⚠ - If
sexpis ALTREP, force materialization and return the SEXP. If not ALTREP, return as-is (no-op).