Changelog
Source:NEWS.md
carrier 0.4.0
CRAN release: 2026-10-28
-
crate()no longer requires.fnto be defined inside the call. Existing functions can now be passed directly:Plain closures have their enclosing environment replaced with the crate’s evaluation environment, equivalent to the previous workaround
crate(rlang::set_env(fn)).Namespace functions and primitives are wrapped in a thin closure that delegates to them, which preserves their internal lookups and avoids a deprecation warning when setting attributes on primitives.
Existing crates are passed through unchanged.
As data declared via
...is only reachable from plain closures, it is an error to supply...when.fnis an existing crate, a namespace function, or a primitive.
The printout of a crate now includes data bound to names starting with a dot.
carrier 0.3.0
Breaking changes
This release modifies the behaviour of functions crated via ..., i.e. in cases like:
foo <- function(x) x + 1
crate(\(x) foo(x), foo = foo)Functions passed through ..., such as foo in this example, are now automatically crated in the same environment as the main crate. This behaviour change may break your code in some cases but has two important benefits that we thought were worth it:
-
In the global environment, it allows helper functions to depend on other helper functions defined globally. Take for instance:
foo <- function(x) bar(x) bar <- function(x) x + 1 crate(\(x) foo(x), foo = foo, bar = bar)Before this change, both
fooandbarwould inherit from the global environment, before and after being sent to a remote context. While the local context has bothfooandbardefined in the global environment, this would not be the case remotely, andfoowould not be able to resolvebar.Now that we recrate all
...closures withing the main crate environment, they are able to see each other. -
In a local environment (e.g. in a function or within
local()), the chain of closure environments used to be included in the crate up to the global environment. This meant the problem descibed in (1) didn’t apply in local environments, but the flip side is that it was also easy to inadvertently capture large objects defined in these environments:local({ large_object <- rnorm(1e8) parameter <- 1 foo <- function(x) x + parameter crate(\(x) foo(x), foo = foo) })In this example,
large_objectwould be included in the crate alongsidefoo, causing performance issues when sending the crate to a remote context. This is no longer possible now thatfoois automatically crated. Any relevant object must be explicitly crated, in one of these ways:
carrier 0.2.0
CRAN release: 2025-06-23
crate()gains a.parent_envargument. The default isbaseenv()in order to isolate the crate from the global search path. You can now set it to another environment. For instance, set it toglobalenv()to make your crate inherit from the search path. Note that, as the global environment is serialized by name rather than by value, the crate is still isolated from objects in the global environment (#16).crate()now requires all...arguments to be named instead of silently dropping unnamed arguments (#15).crate()gains.error_argand.error_callarguments to allow for better error messages when callingcrate()from other functions (#14).
carrier 0.1.1
CRAN release: 2023-04-28
Crated functions no longer carry source references (#6).
Fixed issue that prevented crate sizes to be printed in human-readable format (r-lib/lobstr#60).
carrier 0.1.0
CRAN release: 2018-10-16
Initial release. The package currently only contains a single method for creating crates that requires users to be explicit about what data to pack in the crate. A future release will provide a method to figure out automatically what objects the crate depends on (with inevitable false positives and negatives).