Skip to main content

Module altrep_sexp

Module altrep_sexp 

Source
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 + !Sync wrapper 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 typeALTREP handling
Typed (Vec<i32>, &[f64])Auto-materialized via DATAPTR_RO in TryFromSexp
SEXPAuto-materialized via ensure_materialized in TryFromSexp
AltrepSexpWrapped without materializing. !Send + !Sync.
extern "C-unwind" raw SEXPNo 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§

AltrepSexp
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 sexp is ALTREP, force materialization and return the SEXP. If not ALTREP, return as-is (no-op).