Expand description
Support for R’s missing arguments.
When an R function is called without providing a value for a formal argument,
R passes SEXP::missing_arg() as a placeholder. This is different from NULL -
a missing argument means “not provided”, while NULL is an explicit value.
§Example
use miniextendr_api::{miniextendr, Missing};
#[miniextendr]
fn greet(name: Missing<String>) -> String {
match name.into_option() {
Some(n) => format!("Hello, {}!", n),
None => "Hello, stranger!".to_string(),
}
}In R:
greet("Alice") # "Hello, Alice!"
greet() # "Hello, stranger!"§Difference from Option<T>
Option<T>treatsNULLasNoneand any other value asSome(T).Missing<T>treatsSEXP::missing_arg()as missing and any other value (includingNULL) as present.
Use Missing<Option<T>> if you need to distinguish between:
- Missing argument (not passed)
NULL(explicitly passedNULL)- A value (explicitly passed a non-NULL value)
§How it works: the quote(expr=) trick
In regular R functions, you detect missing arguments with missing():
my_func <- function(x) {
if (missing(x)) "not provided" else x
}
my_func() # "not provided"
my_func(5) # 5However, .Call() (the FFI boundary) forces argument evaluation. Without a
default value, R errors before the call even reaches Rust:
wrapper <- function(x) .Call(rust_fn, x)
wrapper() # Error: argument "x" is missing, with no defaultThe generated R wrappers use quote(expr=) as the default for Missing<T> parameters:
wrapper <- function(x = quote(expr=)) .Call(rust_fn, x)quote(expr=) is an R idiom that captures the “missing” state - calling quote()
without providing its expr argument returns SEXP::missing_arg(). This allows:
- The call to proceed without error
SEXP::missing_arg()to be passed through.Call()to RustMissing<T>to detect it asMissing::Absent
Enums§
- Missing
- Wrapper type that detects if an R argument was not passed (missing).
Functions§
- is_
missing_ arg - Check if a SEXP is the missing argument sentinel.