with_nix() gives you the power of evaluating a main function expr
and its function call stack that are defined in the current R session
in an encapsulated nix-R session defined by Nix expression (default.nix),
which is located in at a distinct project path (project_path).
with_nix() is very convenient because it gives direct code feedback in
read-eval-print-loop style, which gives a direct interface to the very
reproducible infrastructure-as-code approach offered by Nix and Nixpkgs. You
don't need extra efforts such as setting up DevOps tooling like Docker and
domain specific tools like {renv} to control complex software environments
in R and any other language. It is for example useful for the following
purposes.
test compatibility of custom R code and software/package dependencies in
development and production environments
directly stream outputs (returned objects), messages and errors from any
command line tool offered in Nixpkgs into an R session.
Test if evolving R packages change their behavior for given unchanged
R code, and whether they give identical results or not.
with_nix() can evaluate both R code from a nix-R session within
another nix-R session, and also from a host R session (i.e., on macOS or
Linux) within a specific nix-R session. This feature is useful for testing
the reproducibility and compatibility of given code across different software
environments. If testing of different sets of environments is necessary, you
can easily do so by providing Nix expressions in custom .nix or
default.nix files in different subfolders of the project.
rix_init() is run automatically to generate a custom .Rprofile
file for the subshell in project_dir. The defaults in that file ensure
that only R packages from the Nix store, that are defined in the subshell
.nix file are loaded and system's libraries are excluded.
To do its job, with_nix() heavily relies on patterns that manipulate
language expressions (aka computing on the language) offered in base R as
well as the {codetools} package by Luke Tierney.
Some of the key steps that are done behind the scene:
recursively find, classify, and export global objects (globals) in the
call stack of expr as well as propagate R package environments found.
Serialize (save to disk) and deserialize (read from disk) dependent
data structures as .Rds with necessary function arguments provided,
any relevant globals in the call stack, packages, and expr outputs
returned in a temporary directory.
Use pure nix-shell environments to execute a R code script
reconstructed catching expressions with quoting; it is launched by commands
like this via {sys} by Jeroen Ooms:
nix-shell --pure --run "Rscript --vanilla".