Guide
Divergences from GNU R
Intentional differences from GNU R's behavior
miniR intentionally diverges from GNU R where R's behavior is confusing, inconsistent, or unnecessarily restrictive. This is not a drop-in replacement --- it's a fresh implementation that respects R's useful semantics while fixing the bad ones.
Language Improvements
Trailing commas everywhere
GNU R rejects trailing commas in function calls and definitions. miniR allows them in all contexts:
c(1, 2, 3,)
list(a = 1, b = 2,)
data.frame(x = 1:3, y = 4:6,)
function(a, b,) a + b
data.frame() forward references
miniR evaluates columns left-to-right, so later columns can reference earlier ones:
data.frame(x = 1:5, xx = x * x) # works in miniR
data.frame(a = 1:3, b = a + 10L, c = a + b)
Unified pipe operators
|> and %>% are identical in miniR --- both support _ and . placeholders. No library(magrittr) needed:
x |> f(a, _) # R 4.2+ style
x %>% f(a, .) # magrittr style --- same thing
Also native: %<>% (assignment pipe), %T>% (tee pipe), %$% (exposition pipe).
if...else across newlines
if (TRUE) 1
else 2 # works in miniR (GNU R rejects this)
** as power operator
2 ** 3 # 8 --- synonym for ^
Apply Family
vapply is stricter about types
GNU R silently coerces integer results to double when FUN.VALUE = numeric(1).
miniR rejects the type mismatch:
# GNU R: c(1, 2, 3) — silently coerces integer to double
vapply(1:3, function(x) x, numeric(1))
# miniR: error — "values must be type 'double', but result is type 'integer'"
# Fix: be explicit about the return type
vapply(1:3, function(x) as.double(x), numeric(1)) # works
vapply(1:3, function(x) x, integer(1)) # also works
This catches a common source of subtle bugs where the function returns an unexpected type.
vapply accepts fully named arguments
GNU R's vapply requires positional arguments for X, FUN, and FUN.VALUE.
miniR also accepts them by name:
# Works in miniR, not in GNU R
vapply(X = letters[1:3], FUN = nchar, FUN.VALUE = integer(1))
sapply does not preserve input names
GNU R's sapply copies names from the input vector to the result by default
(USE.NAMES = TRUE). miniR currently does not propagate names through sapply.
This is a known gap, not a deliberate divergence.
lapply / Map / Reduce / Filter / Find / Position / Negate
These behave the same as GNU R. All are implemented, including extra-argument
forwarding (lapply(x, f, extra_arg)).
Error Messages
miniR aims for better error messages than GNU R --- more informative, more specific, with suggestions for how to fix the problem.
Tracebacks show C frames
GNU R tracebacks only show opaque .Call entries. miniR unwinds the native stack with DWARF source locations:
Error: value must be non-negative, got -5
Traceback (most recent call last):
2: validate(x)
[C] deep_helper at test.c:36 (stacktest.dylib)
[C] C_validate at test.c:47 (stacktest.dylib)
1: run_check(-5)