| Title: | Run 'Python', 'Julia', 'Rust', and 'C++' Inside 'targets' Pipeline Steps |
|---|---|
| Description: | Adds target constructors that make it easy to use 'Python', 'Julia', 'Rust', and 'C++' inside a 'targets' pipeline using 'reticulate', 'JuliaCall', 'rextendr', and 'Rcpp'. Provides tar_target_py(), tar_target_jl(), tar_target_rs(), and tar_target_cpp() (with matching _raw() variants), each mirroring 'targets' tar_target() and tar_target_raw() functions. 'Python' and 'Julia' steps run a script via a live interpreter with optional R pre- and post-scripts; 'Rust' and 'C++' steps compile functions and call them from an R post-script. Results are then returned either as converted R objects or as files written to disk (format = "file"). Dynamic branching, environment/version selection, a 'crew' controller for isolation, and the full set of tar_target_raw() arguments are supported. |
| Authors: | Pierre Solomon [aut, cre] (ORCID: <https://orcid.org/0000-0001-7187-2664>) |
| Maintainer: | Pierre Solomon <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.3.0 |
| Built: | 2026-10-03 06:54:46 UTC |
| Source: | https://github.com/Pierre9344/tarpolyglot |
Returns a crew::crew_controller_local() tuned for pipelines that run Python or Julia steps. Because reticulate and JuliaCall embed a single interpreter per process (see vignette("get_started", package = "tarpolyglot")), the only way to get a fresh interpreter per target, and to use different environments/versions across targets, is process-level isolation. Passing this controller to targets::tar_option_set() sends targets to separate worker processes; with tasks_max = 1 each worker is retired after one task, so every foreign step gets a clean interpreter that is torn down when the task finishes.
polyglot_controller( workers = 2L, tasks_max = 1L, seconds_idle = 30, log = NULL, ... )polyglot_controller( workers = 2L, tasks_max = 1L, seconds_idle = 30, log = NULL, ... )
workers |
Integer number of parallel worker processes. Default |
tasks_max |
Integer max tasks a worker runs before it is retired (and its embedded interpreter torn down). Default |
seconds_idle |
Numeric seconds an idle worker waits before shutting down. Default |
log |
Optional |
... |
Further arguments passed to |
This is the recommended default for polyglot pipelines. Put it near the top of _targets.R:
targets::tar_option_set(controller = tarpolyglot::polyglot_controller())
A crew controller object, ready for targets::tar_option_set(controller = ...).
tar_target_py(), tar_target_jl(), tar_polyglot_log()
# Constructing a controller starts no worker process: targets launches them # when the pipeline runs, so this example needs no Python. controller <- polyglot_controller(workers = 4L) inherits(controller, "crew_class_controller") # In _targets.R you hand it to targets::tar_option_set(), alongside the # steps that will use it. The option is reset here so the example leaves # no global state behind. targets::tar_option_set(controller = controller) list( tar_target_py(x, "scripts/step.py", retrieve = "result") ) targets::tar_option_reset()# Constructing a controller starts no worker process: targets launches them # when the pipeline runs, so this example needs no Python. controller <- polyglot_controller(workers = 4L) inherits(controller, "crew_class_controller") # In _targets.R you hand it to targets::tar_option_set(), alongside the # steps that will use it. The option is reset here so the example leaves # no global state behind. targets::tar_option_set(controller = controller) list( tar_target_py(x, "scripts/step.py", retrieve = "result") ) targets::tar_option_reset()
Compiles the // [[Rcpp::export]] functions in a C++ script with Rcpp::sourceCpp(), exposing them as R functions in a fresh environment, then evaluates an R post-script in that environment where you call those functions and return the result. Upstream inputs are bound in the same environment. This is the function the target built by tar_target_cpp() calls; it is exported so the call resolves at run time, but package users should not call it directly.
run_cpp_step( script, post_script = NULL, inputs = list(), output = "object", files = NULL, depends = NULL, name = NULL )run_cpp_step( script, post_script = NULL, inputs = list(), output = "object", files = NULL, depends = NULL, name = NULL )
script |
Path to the C++ script containing |
post_script |
Path to an R script evaluated after compilation. The compiled C++ functions and the named |
inputs |
Named character vector (or list) mapping the name seen inside the step (in the R environment and, after the hand-off, in the foreign session) to the name of an upstream target, e.g. |
output |
Output mode: |
files |
Optional character vector of file paths to return when no |
depends |
Optional character vector of extension packages (e.g. |
name |
Character string, the step's target name. Supplied automatically by the constructor; used only to name this step's log files when |
Unlike Python/Julia there is no pre-script for C++ and no live interpreter: sourceCpp() compiles a shared library and R calls into it with real type conversion (via Rcpp). Header-only extension packages such as RcppArmadillo/RcppEigen need no special handling: declare them with a // [[Rcpp::depends(pkgname)]] attribute directly in the C++ source, exactly as in any other Rcpp usage, and sourceCpp() picks it up. sourceCpp() compiles via R's own configured toolchain (R CMD SHLIB), so, unlike Rust, there is no separate compiler/ABI to match – on Windows this function still puts Rtools on PATH for the build itself, since a bare or crew-worker process may not otherwise have it there.
The value of the post-script (object mode) or a character vector of normalised file paths (file mode).
A worker receives whatever the constructor already resolved, which is one of two things: a path to a file on disk, or an inline carrier built by tar_code() that holds the code in memory. Both are accepted, so a direct call may pass either.
tar_target_path() is deliberately not a third form at this level. It is a constructor-level convenience: tar_target_py() and the other constructors rewrite it while the pipeline's DAG is built, so that by the time a worker runs it has already become the ordinary file path held by the upstream target. Handing the result of tar_target_path() straight to a worker therefore does not resolve to a file. The three forms as written in _targets.R, and which of them tracks your edits, are covered in vignette("scripts").
tar_target_cpp(), run_py_step(), run_jl_step(), run_rs_step()
# This worker compiles C++, so it only runs when TARPOLYGLOT_EXAMPLES=true # says a compiler reachable by R is available. tar_dir() runs the code in a # temporary directory. if (identical(Sys.getenv("TARPOLYGLOT_EXAMPLES"), "true")) { targets::tar_dir({ # Normally invoked by tar_target_cpp(); shown here as a direct call. writeLines( c("#include <Rcpp.h>", "// [[Rcpp::export]]", "double square(double x) { return x * x; }"), "square.cpp" ) writeLines("square(x)", "post.R") run_cpp_step( script = "square.cpp", inputs = list(x = 21), post_script = "post.R" ) }) }# This worker compiles C++, so it only runs when TARPOLYGLOT_EXAMPLES=true # says a compiler reachable by R is available. tar_dir() runs the code in a # temporary directory. if (identical(Sys.getenv("TARPOLYGLOT_EXAMPLES"), "true")) { targets::tar_dir({ # Normally invoked by tar_target_cpp(); shown here as a direct call. writeLines( c("#include <Rcpp.h>", "// [[Rcpp::export]]", "double square(double x) { return x * x; }"), "square.cpp" ) writeLines("square(x)", "post.R") run_cpp_step( script = "square.cpp", inputs = list(x = 21), post_script = "post.R" ) }) }
Julia counterpart of run_py_step(). Runs, inside a fresh R environment, an optional R pre-script, a Python script (via JuliaCall). This is the function the target built by tar_target_jl() calls; it is exported so that call resolves at pipeline run time but this function is not destined to be called directly by the package users.
run_jl_step( script, pre_script = NULL, post_script = NULL, inputs = list(), output = "object", retrieve = NULL, files = NULL, julia_version = NULL, julia_home = getOption("tarpolyglot.julia_home"), julia_project = NULL, julia_packages = NULL, name = NULL )run_jl_step( script, pre_script = NULL, post_script = NULL, inputs = list(), output = "object", retrieve = NULL, files = NULL, julia_version = NULL, julia_home = getOption("tarpolyglot.julia_home"), julia_project = NULL, julia_packages = NULL, name = NULL )
script |
Path to the Julia script to run (required). Accepts a file path or an inline |
pre_script |
Optional path to an R script run before the Julia script. It is evaluated in the step environment, which already holds the named |
post_script |
Optional path to an R script run after the Julia script. It is evaluated in the same environment, which now also holds |
inputs |
Named list of upstream target values, bound by name into the step environment. Supplied automatically by the constructor. |
output |
Output mode: |
retrieve |
Optional character vector of foreign-session variable names to return when no |
files |
Optional character vector of file paths to return when no |
julia_version |
Optional Julia version to select (e.g. |
julia_home, julia_project, julia_packages
|
Julia environment selection. |
name |
Character string, the step's target name. Supplied automatically by the constructor; used only to name this step's log files when |
The converted R object (object mode) or a character vector of normalised file paths (file mode).
A worker receives whatever the constructor already resolved, which is one of two things: a path to a file on disk, or an inline carrier built by tar_code() that holds the code in memory. Both are accepted, so a direct call may pass either.
tar_target_path() is deliberately not a third form at this level. It is a constructor-level convenience: tar_target_py() and the other constructors rewrite it while the pipeline's DAG is built, so that by the time a worker runs it has already become the ordinary file path held by the upstream target. Handing the result of tar_target_path() straight to a worker therefore does not resolve to a file. The three forms as written in _targets.R, and which of them tracks your edits, are covered in vignette("scripts").
run_py_step(), tar_target_jl()
# This worker starts a live Julia session, so it only runs when # TARPOLYGLOT_EXAMPLES=true says a Julia toolchain is available. # tar_dir() runs the code in a temporary directory. if (identical(Sys.getenv("TARPOLYGLOT_EXAMPLES"), "true")) { targets::tar_dir({ # Normally invoked by tar_target_jl(); shown here as a direct call. writeLines("to_jl <- list(x = x)", "pre.R") writeLines("result = sum(x)", "sum.jl") run_jl_step( script = "sum.jl", pre_script = "pre.R", inputs = list(x = c(1, 2, 3)), retrieve = "result" ) }) }# This worker starts a live Julia session, so it only runs when # TARPOLYGLOT_EXAMPLES=true says a Julia toolchain is available. # tar_dir() runs the code in a temporary directory. if (identical(Sys.getenv("TARPOLYGLOT_EXAMPLES"), "true")) { targets::tar_dir({ # Normally invoked by tar_target_jl(); shown here as a direct call. writeLines("to_jl <- list(x = x)", "pre.R") writeLines("result = sum(x)", "sum.jl") run_jl_step( script = "sum.jl", pre_script = "pre.R", inputs = list(x = c(1, 2, 3)), retrieve = "result" ) }) }
Runs, inside a fresh R environment, an optional R pre-script, a Python script (via reticulate), and an optional R post-script, then returns either a converted R object or a character vector of files. This is the function the target built by tar_target_py() calls; it is exported so that call resolves at pipeline run time but this function is not destined to be called directly by the package users.
run_py_step( script, pre_script = NULL, post_script = NULL, inputs = list(), output = "object", retrieve = NULL, files = NULL, python_version = NULL, env = NULL, env_manager = "system", python = NULL, name = NULL )run_py_step( script, pre_script = NULL, post_script = NULL, inputs = list(), output = "object", retrieve = NULL, files = NULL, python_version = NULL, env = NULL, env_manager = "system", python = NULL, name = NULL )
script |
Path to the Python script to run (required). Accepts a file path or an inline |
pre_script |
Optional path to an R script run before the Python script. It is evaluated in the step environment, which already holds the named |
post_script |
Optional path to an R script run after the Python script. It is evaluated in the same environment, which now also holds |
inputs |
Named list of upstream target values, bound by name into the step environment. Supplied automatically by the constructor. |
output |
Output mode: |
retrieve |
Optional character vector of foreign-session variable names to return when no |
files |
Optional character vector of file paths to return when no |
python_version |
Optional Python version to select (e.g. |
env, env_manager, python
|
Python environment selection: the reproducible alternatives to |
name |
Character string, the step's target name. Supplied automatically by the constructor; used only to name this step's log files when |
The converted R object (object mode) or a character vector of normalised file paths (file mode).
A worker receives whatever the constructor already resolved, which is one of two things: a path to a file on disk, or an inline carrier built by tar_code() that holds the code in memory. Both are accepted, so a direct call may pass either.
tar_target_path() is deliberately not a third form at this level. It is a constructor-level convenience: tar_target_py() and the other constructors rewrite it while the pipeline's DAG is built, so that by the time a worker runs it has already become the ordinary file path held by the upstream target. Handing the result of tar_target_path() straight to a worker therefore does not resolve to a file. The three forms as written in _targets.R, and which of them tracks your edits, are covered in vignette("scripts").
run_jl_step(), tar_target_py()
# This worker binds a live Python interpreter, so it only runs when # TARPOLYGLOT_EXAMPLES=true says a Python toolchain is available. # tar_dir() runs the code in a temporary directory, so nothing is written # to the working directory. if (identical(Sys.getenv("TARPOLYGLOT_EXAMPLES"), "true")) { targets::tar_dir({ # Normally invoked by tar_target_py(); shown here as a direct call. writeLines("to_py <- list(x = x)", "pre.R") writeLines("result = float(sum(x))", "sum.py") run_py_step( script = "sum.py", pre_script = "pre.R", inputs = list(x = c(1, 2, 3)), retrieve = "result" ) }) }# This worker binds a live Python interpreter, so it only runs when # TARPOLYGLOT_EXAMPLES=true says a Python toolchain is available. # tar_dir() runs the code in a temporary directory, so nothing is written # to the working directory. if (identical(Sys.getenv("TARPOLYGLOT_EXAMPLES"), "true")) { targets::tar_dir({ # Normally invoked by tar_target_py(); shown here as a direct call. writeLines("to_py <- list(x = x)", "pre.R") writeLines("result = float(sum(x))", "sum.py") run_py_step( script = "sum.py", pre_script = "pre.R", inputs = list(x = c(1, 2, 3)), retrieve = "result" ) }) }
Compiles the #[extendr] functions in a Rust script with rextendr::rust_source(), exposing them as R functions in a fresh environment, then evaluates an R post-script in that environment where you call those functions and return the result. Upstream inputs are bound in the same environment. This is the function the target built by tar_target_rs() calls; it is exported so the call resolves at run time, but package users should not call it directly.
run_rs_step( script, post_script = NULL, inputs = list(), output = "object", files = NULL, dependencies = NULL, features = NULL, profile = NULL, toolchain = NULL )run_rs_step( script, post_script = NULL, inputs = list(), output = "object", files = NULL, dependencies = NULL, features = NULL, profile = NULL, toolchain = NULL )
script |
Path to the Rust script containing |
post_script |
Path to an R script evaluated after compilation. The compiled Rust functions and the named |
inputs |
Named character vector (or list) mapping the name seen inside the step (in the R environment and, after the hand-off, in the foreign session) to the name of an upstream target, e.g. |
output |
Output mode: |
files |
Optional character vector of file paths to return when no |
dependencies, features, profile
|
Passed to |
toolchain |
Optional rustup toolchain (e.g. |
Unlike Python/Julia there is no pre-script for Rust and no live interpreter: rust_source() compiles a dynamic library and R calls into it with real type conversion (via extendr). A Rust toolchain and cargo must be reachable (this function puts R, cargo, and on Windows Rtools on PATH for the build itself); on Windows use the GNU toolchain.
The value of the post-script (object mode) or a character vector of normalised file paths (file mode).
A worker receives whatever the constructor already resolved, which is one of two things: a path to a file on disk, or an inline carrier built by tar_code() that holds the code in memory. Both are accepted, so a direct call may pass either.
tar_target_path() is deliberately not a third form at this level. It is a constructor-level convenience: tar_target_py() and the other constructors rewrite it while the pipeline's DAG is built, so that by the time a worker runs it has already become the ordinary file path held by the upstream target. Handing the result of tar_target_path() straight to a worker therefore does not resolve to a file. The three forms as written in _targets.R, and which of them tracks your edits, are covered in vignette("scripts").
tar_target_rs(), run_py_step(), run_jl_step()
# This worker compiles Rust with cargo, so it only runs when # TARPOLYGLOT_EXAMPLES=true says a Rust toolchain is available. # tar_dir() runs the code in a temporary directory. if (identical(Sys.getenv("TARPOLYGLOT_EXAMPLES"), "true")) { targets::tar_dir({ # Normally invoked by tar_target_rs(); shown here as a direct call. writeLines("#[extendr] fn square(x: f64) -> f64 { x * x }", "square.rs") writeLines("square(x)", "post.R") run_rs_step( script = "square.rs", inputs = list(x = 21), post_script = "post.R" ) }) }# This worker compiles Rust with cargo, so it only runs when # TARPOLYGLOT_EXAMPLES=true says a Rust toolchain is available. # tar_dir() runs the code in a temporary directory. if (identical(Sys.getenv("TARPOLYGLOT_EXAMPLES"), "true")) { targets::tar_dir({ # Normally invoked by tar_target_rs(); shown here as a direct call. writeLines("#[extendr] fn square(x: f64) -> f64 { x * x }", "square.rs") writeLines("square(x)", "post.R") run_rs_step( script = "square.rs", inputs = list(x = 21), post_script = "post.R" ) }) }
Use in place of a file-path string (or a tar_target_path() reference) for the
script, pre_script, or post_script argument of the tar_target_py() /
tar_target_jl() / tar_target_rs() constructors (and their _raw forms), to
supply the code inline instead of pointing at a file.
tar_code(x)tar_code(x)
x |
Inline code: an R |
tar_code() accepts two forms. An R {...} block is captured as inline R code and is only valid in an R slot (pre_script or post_script); passing a block as the foreign script is an error. Anything that evaluates to a single character string is treated as inline source code, and its language follows from the slot it fills: the foreign script slot is Python, Julia, or Rust source, while a pre_script or post_script slot is R source.
Multi-line strings are supported and preserved verbatim, then dedented: the
common leading-whitespace margin shared by all lines is stripped (and leading/
trailing blank lines dropped), so code you indent to line up with the surrounding
_targets.R still starts flush-left. This matters for Python, whose top-level
indentation is significant; Julia/Rust/R are unaffected either way. For Python or
regex payloads, prefer an R raw string r"( ... )" so backslashes and quotes need
no escaping.
Because the inline code is embedded in the target's command, targets hashes it:
editing inline code re-runs the target automatically (unlike a literal path string,
which is untracked).
A classed marker (tp_inline) recognised by the tar_target_* constructors.
tar_target_path(), tar_target_py(), tar_target_jl(), tar_target_rs()
# Building a target does not run it, so these examples need no Python. # Inline R (pre/post) plus a one-line inline Python `script`: tarpolyglot::tar_target_py( name = m, inputs = c(x = "prepared_x"), pre_script = tar_code({ to_py <- list(x = x) }), # inline R script = tar_code("result = float(sum(x))"), # inline Python post_script = tar_code({ py_get("result") }) ) # Multi-line inline Python. Indent the code to line up with `_targets.R`; # tar_code() dedents it, so Python's own block indentation stays correct. tarpolyglot::tar_target_py( name = pos_sum, inputs = c(x = "prepared_x"), script = tar_code(r"( result = 0 for v in x: if v > 0: result += v )") )# Building a target does not run it, so these examples need no Python. # Inline R (pre/post) plus a one-line inline Python `script`: tarpolyglot::tar_target_py( name = m, inputs = c(x = "prepared_x"), pre_script = tar_code({ to_py <- list(x = x) }), # inline R script = tar_code("result = float(sum(x))"), # inline Python post_script = tar_code({ py_get("result") }) ) # Multi-line inline Python. Indent the code to line up with `_targets.R`; # tar_code() dedents it, so Python's own block indentation stays correct. tarpolyglot::tar_target_py( name = pos_sum, inputs = c(x = "prepared_x"), script = tar_code(r"( result = 0 for v in x: if v > 0: result += v )") )
Passed to polyglot_controller()'s log argument to write one log file per Python/Julia step: <name>.out for stdout, <name>.err for stderr, named after the target. crew launches worker processes before it knows which target they will run, so this configuration cannot be applied at worker-launch time; instead polyglot_controller() stashes it as environment variables (inherited by every worker process it spawns, the same way any other environment variable is), and run_py_step() / run_jl_step() read them back and do the actual redirection once they know which step is running and what interpreter it resolved.
tar_polyglot_log( stdout = "./logs/out", stderr = "./logs/err", append = FALSE, header = TRUE )tar_polyglot_log( stdout = "./logs/out", stderr = "./logs/err", append = FALSE, header = TRUE )
stdout, stderr
|
Directory to write per-step log files into (created if missing), or |
append |
If |
header |
If |
Rust steps (tar_target_rs()) are not covered: rextendr-compiled code writes straight to the OS file descriptor, bypassing the redirection mechanism reticulate/JuliaCall provide for their embedded interpreters. Use crew's own options_local(log_directory = ...) (process-level logging; since polyglot_controller() defaults to tasks_max = 1, each worker runs exactly one step, so that already gives one log per step, Rust included) if you need Rust step output.
C++ steps (tar_target_cpp()) are covered, with one caveat: Rcpp::Rcout/Rcpp::Rcerr (the idiomatic Rcpp printing calls) route through R's own output-connection system, so they are captured by an R-level sink() redirect the same way cat()/message() output is (confirmed empirically, including from a fresh crew worker process). Raw std::cout/std::cerr/printf() writes bypass R's connection system entirely and write straight to the OS file descriptor, exactly like Rust's println!() – not captured here; use Rcpp::Rcout/Rcpp::Rcerr in compiled code instead of raw C++ streams if you want step output in these logs.
Branches of one pattern share a single log file, language-agnostically. The log file name is fixed to the target's name at the moment its command is built, before branching happens – so every branch of a map()/tarpolyglot_map()-driven step (Python, Julia, or C++ alike) writes to the same <name>.out/<name>.err, and since append = FALSE truncates at the start of each branch's run, only the last branch to run leaves its output in the file; earlier branches' output is overwritten, not lost-and-gone from disk but never actually visible. Not specific to C++ – confirmed while investigating C++ logging, but the same file-per-target-name design applies to every constructor. Use append = TRUE to at least keep all branches' output (separated, in run order) instead of losing all but the last, or crew's own options_local(log_directory = ...) for a genuinely one-file-per-worker-process log.
A list with class tp_log, for polyglot_controller(log = ...).
# tar_polyglot_log() only builds a configuration object; nothing is written # and no directory is created until a step actually runs. log <- tar_polyglot_log(stdout = "./logs/out", stderr = "./logs/err") str(log) # It is passed to polyglot_controller(), which every Python/Julia/C++ step # then inherits from. controller <- polyglot_controller(log = log) inherits(controller, "crew_class_controller")# tar_polyglot_log() only builds a configuration object; nothing is written # and no directory is created until a step actually runs. log <- tar_polyglot_log(stdout = "./logs/out", stderr = "./logs/err") str(log) # It is passed to polyglot_controller(), which every Python/Julia/C++ step # then inherits from. controller <- polyglot_controller(log = log) inherits(controller, "crew_class_controller")
Non-standard-evaluation constructor mirroring targets::tar_target() for C++: pass a bare name and unquoted pattern, for direct use in _targets.R. Compiles the // [[Rcpp::export]] functions in script with Rcpp::sourceCpp() and calls them from the R post_script. Delegates to tar_target_cpp_raw(); see it and run_cpp_step() for the full reference. The Rust twin is tar_target_rs(); Python/Julia are tar_target_py() / tar_target_jl().
tar_target_cpp( name, script, post_script = NULL, inputs = NULL, output = "object", files = NULL, depends = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )tar_target_cpp( name, script, post_script = NULL, inputs = NULL, output = "object", files = NULL, depends = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )
name |
Symbol, the target name (unquoted). |
script |
Path to the C++ script with |
post_script |
Path to an R script run after compilation, where the compiled functions and |
inputs |
Named character vector (or list) mapping the name seen inside the step (in the R environment and, after the hand-off, in the foreign session) to the name of an upstream target, e.g. |
output |
Output mode: |
files |
Optional character vector of file paths to return when no |
depends |
Optional character vector of extension packages (e.g. |
pattern |
Optional branching pattern as described in the targets package documentation, unquoted (e.g. |
packages, library
|
Character vectors of R packages (and library paths) to load for the target, forwarded to |
deps, string
|
Advanced |
format, repository, iteration
|
Storage/iteration settings forwarded to |
error, memory, garbage_collection, deployment, priority, resources, storage, retrieval, cue, description
|
Standard |
A targets target object. When pattern uses tarpolyglot_map() it is instead a list of two targets: the <name>_cpp_lib compile target and the branched <name> target.
Every script argument (script, and pre_script / post_script where the constructor has them) accepts the same three forms. The choice is not cosmetic: it decides whether editing the code re-runs the target.
e.g. script = "py/step.py". The file is read when the step runs, but it is not tracked, so editing it does not invalidate the target: targets will happily reuse a stale result until some other dependency changes. Simplest form, and a reasonable default once a script has settled.
tar_target_path() referencee.g. script = tar_target_path("step_py"), naming an upstream tar_target(step_py, "py/step.py", format = "file"). The file becomes a real targets dependency, so editing it does invalidate this target and the step re-runs. This is what you want while a script is still changing, and the recommended form for reproducible pipelines.
tar_code()
e.g. script = tar_code("result = sum(x)"). The code lives in _targets.R rather than in a file, and is embedded in the target's command, so targets hashes it and editing it does invalidate the target. A character string carries foreign source (Python, Julia, Rust, C++) or R source; an R { ... } block carries inline R and is accepted only by pre_script / post_script, never by the foreign script.
Mixing forms in one call is fine: a tracked script with a literal post_script, inline code for one and a file for another, and so on. See vignette("scripts") for worked examples of all three and guidance on choosing.
tar_target_cpp_raw(), tarpolyglot_map(), run_cpp_step(), tar_target_rs(), tar_target_py(), tar_target_jl()
# Building a target does not run it, so these examples need no C++ compiler. # scripts/square.cpp: # // [[Rcpp::export]] # double square(double x) { return x * x; } # scripts/post.R: # square(x) list( tarpolyglot::tar_target_cpp( name = cpp_square, script = "scripts/square.cpp", inputs = c(x = "value"), post_script = "scripts/post.R" ) ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_cpp( name = demo_literal, script = "cpp/step.cpp", post_script = "R/post.R" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_cpp, "cpp/step.cpp", format = "file"), tarpolyglot::tar_target_cpp( name = demo_tracked, script = tarpolyglot::tar_target_path("step_cpp"), post_script = "R/post.R" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_cpp( name = demo_inline, script = tarpolyglot::tar_code( "// [[Rcpp::export]]\nint one() { return 1; }" ), post_script = tarpolyglot::tar_code({ one() }) )# Building a target does not run it, so these examples need no C++ compiler. # scripts/square.cpp: # // [[Rcpp::export]] # double square(double x) { return x * x; } # scripts/post.R: # square(x) list( tarpolyglot::tar_target_cpp( name = cpp_square, script = "scripts/square.cpp", inputs = c(x = "value"), post_script = "scripts/post.R" ) ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_cpp( name = demo_literal, script = "cpp/step.cpp", post_script = "R/post.R" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_cpp, "cpp/step.cpp", format = "file"), tarpolyglot::tar_target_cpp( name = demo_tracked, script = tarpolyglot::tar_target_path("step_cpp"), post_script = "R/post.R" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_cpp( name = demo_inline, script = tarpolyglot::tar_code( "// [[Rcpp::export]]\nint one() { return 1; }" ), post_script = tarpolyglot::tar_code({ one() }) )
Character-based constructor mirroring targets::tar_target_raw() for C++, for use inside targets factories. Returns a single targets target whose command compiles the // [[Rcpp::export]] functions in script with Rcpp::sourceCpp() and then evaluates an R post-script that calls those functions (with the upstream inputs in scope) and returns the value. See run_cpp_step() for the contract. For direct use in _targets.R, see tar_target_cpp().
tar_target_cpp_raw( name, script, post_script = NULL, inputs = NULL, output = "object", files = NULL, depends = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )tar_target_cpp_raw( name, script, post_script = NULL, inputs = NULL, output = "object", files = NULL, depends = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )
name |
Character string, the target name. |
script |
Path to the C++ script with |
post_script |
Path to an R script run after compilation, where the compiled functions and |
inputs |
Named character vector (or list) mapping the name seen inside the step (in the R environment and, after the hand-off, in the foreign session) to the name of an upstream target, e.g. |
output |
Output mode: |
files |
Optional character vector of file paths to return when no |
depends |
Optional character vector of extension packages (e.g. |
pattern |
Optional branching pattern as described in the targets package documentation, as a language object (e.g. |
packages, library
|
Character vectors of R packages (and library paths) to load for the target, forwarded to |
deps, string
|
Advanced |
format, repository, iteration
|
Storage/iteration settings forwarded to |
error, memory, garbage_collection, deployment, priority, resources, storage, retrieval, cue, description
|
Standard |
Unlike Python/Julia there is no pre-script for C++: inputs are used directly in the post-script alongside the compiled functions, mirroring tar_target_rs(). A working C++ compiler is required; sourceCpp() compiles via R's own configured toolchain (R CMD SHLIB), so, unlike Rust, there is no separate compiler/ABI to match – on Windows Rtools must be installed and discoverable the same way it already needs to be for any R package with compiled code.
Under dynamic branching, pattern = map(...) recompiles the library in every branch (C++ has no live interpreter to reuse, the same limitation Rust has). Passing a tarpolyglot pattern helper instead (tarpolyglot_map(), tarpolyglot_cross(), tarpolyglot_slice(), tarpolyglot_head(), tarpolyglot_tail(), tarpolyglot_sample()) compiles the library once in a companion target named <name>_cpp_lib and reuses it across all branches; the constructor then returns both targets as a list. See tarpolyglot_map().
A targets target object. When pattern uses tarpolyglot_map() it is instead a list of two targets: the <name>_cpp_lib compile target and the branched <name> target.
Every script argument (script, and pre_script / post_script where the constructor has them) accepts the same three forms. The choice is not cosmetic: it decides whether editing the code re-runs the target.
e.g. script = "py/step.py". The file is read when the step runs, but it is not tracked, so editing it does not invalidate the target: targets will happily reuse a stale result until some other dependency changes. Simplest form, and a reasonable default once a script has settled.
tar_target_path() referencee.g. script = tar_target_path("step_py"), naming an upstream tar_target(step_py, "py/step.py", format = "file"). The file becomes a real targets dependency, so editing it does invalidate this target and the step re-runs. This is what you want while a script is still changing, and the recommended form for reproducible pipelines.
tar_code()
e.g. script = tar_code("result = sum(x)"). The code lives in _targets.R rather than in a file, and is embedded in the target's command, so targets hashes it and editing it does invalidate the target. A character string carries foreign source (Python, Julia, Rust, C++) or R source; an R { ... } block carries inline R and is accepted only by pre_script / post_script, never by the foreign script.
Mixing forms in one call is fine: a tracked script with a literal post_script, inline code for one and a file for another, and so on. See vignette("scripts") for worked examples of all three and guidance on choosing.
tar_target_cpp(), tarpolyglot_map(), run_cpp_step(), tar_target_rs_raw(), tar_target_py_raw(), tar_target_jl_raw()
# Building a target does not run it, so these examples need no C++ compiler. # scripts/square.cpp: # // [[Rcpp::export]] # double square(double x) { return x * x; } # scripts/post.R: # square(x) tarpolyglot::tar_target_cpp_raw( name = "cpp_square", script = "scripts/square.cpp", inputs = c(x = "value"), post_script = "scripts/post.R" ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_cpp_raw( name = "demo_literal", script = "cpp/step.cpp", post_script = "R/post.R" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_cpp, "cpp/step.cpp", format = "file"), tarpolyglot::tar_target_cpp_raw( name = "demo_tracked", script = tarpolyglot::tar_target_path("step_cpp"), post_script = "R/post.R" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_cpp_raw( name = "demo_inline", script = tarpolyglot::tar_code( "// [[Rcpp::export]]\nint one() { return 1; }" ), post_script = tarpolyglot::tar_code({ one() }) )# Building a target does not run it, so these examples need no C++ compiler. # scripts/square.cpp: # // [[Rcpp::export]] # double square(double x) { return x * x; } # scripts/post.R: # square(x) tarpolyglot::tar_target_cpp_raw( name = "cpp_square", script = "scripts/square.cpp", inputs = c(x = "value"), post_script = "scripts/post.R" ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_cpp_raw( name = "demo_literal", script = "cpp/step.cpp", post_script = "R/post.R" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_cpp, "cpp/step.cpp", format = "file"), tarpolyglot::tar_target_cpp_raw( name = "demo_tracked", script = tarpolyglot::tar_target_path("step_cpp"), post_script = "R/post.R" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_cpp_raw( name = "demo_inline", script = tarpolyglot::tar_code( "// [[Rcpp::export]]\nint one() { return 1; }" ), post_script = tarpolyglot::tar_code({ one() }) )
Non-standard-evaluation constructor mirroring targets::tar_target(): pass a bare name and unquoted pattern, for direct use in _targets.R. Delegates to tar_target_jl_raw(); see it and run_jl_step() for the full reference. The Python twin is tar_target_py().
tar_target_jl( name, script, pre_script = NULL, post_script = NULL, inputs = NULL, output = "object", retrieve = NULL, files = NULL, julia_version = NULL, julia_home = getOption("tarpolyglot.julia_home"), julia_project = NULL, julia_packages = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )tar_target_jl( name, script, pre_script = NULL, post_script = NULL, inputs = NULL, output = "object", retrieve = NULL, files = NULL, julia_version = NULL, julia_home = getOption("tarpolyglot.julia_home"), julia_project = NULL, julia_packages = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )
name |
Symbol, the target name (unquoted). |
script |
Path to the Julia script to run (required). Accepts a literal path, a |
pre_script |
Optional path to an R script run before the Julia script. See |
post_script |
Optional path to an R script run after the Julia script. See |
inputs |
Named character vector (or list) mapping the name seen inside the step (in the R environment and, after the hand-off, in the foreign session) to the name of an upstream target, e.g. |
output |
Output mode: |
retrieve |
Optional character vector of foreign-session variable names to return when no |
files |
Optional character vector of file paths to return when no |
julia_version |
Optional Julia version to select (e.g. |
julia_home, julia_project, julia_packages
|
Julia environment selection, forwarded to |
pattern |
Optional dynamic-branching pattern, unquoted (e.g. |
packages, library
|
Character vectors of R packages (and library paths) to load for the target, forwarded to |
deps, string
|
Advanced |
format, repository, iteration
|
Storage/iteration settings forwarded to |
error, memory, garbage_collection, deployment, priority, resources, storage, retrieval, cue, description
|
Standard |
A targets target object.
Every script argument (script, and pre_script / post_script where the constructor has them) accepts the same three forms. The choice is not cosmetic: it decides whether editing the code re-runs the target.
e.g. script = "py/step.py". The file is read when the step runs, but it is not tracked, so editing it does not invalidate the target: targets will happily reuse a stale result until some other dependency changes. Simplest form, and a reasonable default once a script has settled.
tar_target_path() referencee.g. script = tar_target_path("step_py"), naming an upstream tar_target(step_py, "py/step.py", format = "file"). The file becomes a real targets dependency, so editing it does invalidate this target and the step re-runs. This is what you want while a script is still changing, and the recommended form for reproducible pipelines.
tar_code()
e.g. script = tar_code("result = sum(x)"). The code lives in _targets.R rather than in a file, and is embedded in the target's command, so targets hashes it and editing it does invalidate the target. A character string carries foreign source (Python, Julia, Rust, C++) or R source; an R { ... } block carries inline R and is accepted only by pre_script / post_script, never by the foreign script.
Mixing forms in one call is fine: a tracked script with a literal post_script, inline code for one and a file for another, and so on. See vignette("scripts") for worked examples of all three and guidance on choosing.
tar_target_jl_raw(), run_jl_step(), tar_target_py()
# Building a target does not run it, so these examples need no Julia. # scripts/sum.jl: # result = sum(x) # scripts/post.R: # jl_get("result") list( tarpolyglot::tar_target_jl( name = jl_sum, script = "scripts/sum.jl", inputs = c(x = "prepared_x"), post_script = "scripts/post.R" ) ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_jl( name = demo_literal, script = "jl/step.jl", retrieve = "result" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_jl, "jl/step.jl", format = "file"), tarpolyglot::tar_target_jl( name = demo_tracked, script = tarpolyglot::tar_target_path("step_jl"), retrieve = "result" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_jl( name = demo_inline, script = tarpolyglot::tar_code("result = 1 + 1"), post_script = tarpolyglot::tar_code({ jl_get("result") }) ) # Tracking a helper file the script includes. Point `inputs` at a # format = "file" target so editing the helper also re-runs the step; # `inputs` takes the *target* name, not the path. Julia resolves a # relative include() against the including file's own directory, so make # the path absolute. jl/step.jl is then: # include(helper_path) # result = sum(myscale(x)) list( targets::tar_target(helper_file, "jl/helper.jl", format = "file"), tarpolyglot::tar_target_jl( name = demo_helper, script = "jl/step.jl", inputs = c(x = "prepared_x", helper_path = "helper_file"), pre_script = tarpolyglot::tar_code({ to_jl <- list(x = x, helper_path = normalizePath(helper_path, winslash = "/")) }), retrieve = "result" ) )# Building a target does not run it, so these examples need no Julia. # scripts/sum.jl: # result = sum(x) # scripts/post.R: # jl_get("result") list( tarpolyglot::tar_target_jl( name = jl_sum, script = "scripts/sum.jl", inputs = c(x = "prepared_x"), post_script = "scripts/post.R" ) ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_jl( name = demo_literal, script = "jl/step.jl", retrieve = "result" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_jl, "jl/step.jl", format = "file"), tarpolyglot::tar_target_jl( name = demo_tracked, script = tarpolyglot::tar_target_path("step_jl"), retrieve = "result" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_jl( name = demo_inline, script = tarpolyglot::tar_code("result = 1 + 1"), post_script = tarpolyglot::tar_code({ jl_get("result") }) ) # Tracking a helper file the script includes. Point `inputs` at a # format = "file" target so editing the helper also re-runs the step; # `inputs` takes the *target* name, not the path. Julia resolves a # relative include() against the including file's own directory, so make # the path absolute. jl/step.jl is then: # include(helper_path) # result = sum(myscale(x)) list( targets::tar_target(helper_file, "jl/helper.jl", format = "file"), tarpolyglot::tar_target_jl( name = demo_helper, script = "jl/step.jl", inputs = c(x = "prepared_x", helper_path = "helper_file"), pre_script = tarpolyglot::tar_code({ to_jl <- list(x = x, helper_path = normalizePath(helper_path, winslash = "/")) }), retrieve = "result" ) )
Character-based constructor mirroring targets::tar_target_raw(): name is a string and it is meant for use inside targets factories. Returns a single targets target whose command runs an optional R pre-script, script (via JuliaCall), and an optional R post-script, then returns a converted R object or a character vector of files. See run_jl_step() for the pre/post-script contract (the to_jl hand-off and the jl_get / jl_call helpers). For direct use in _targets.R, see tar_target_jl(). The Python twin is tar_target_py_raw().
tar_target_jl_raw( name, script, pre_script = NULL, post_script = NULL, inputs = NULL, output = "object", retrieve = NULL, files = NULL, julia_version = NULL, julia_home = getOption("tarpolyglot.julia_home"), julia_project = NULL, julia_packages = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )tar_target_jl_raw( name, script, pre_script = NULL, post_script = NULL, inputs = NULL, output = "object", retrieve = NULL, files = NULL, julia_version = NULL, julia_home = getOption("tarpolyglot.julia_home"), julia_project = NULL, julia_packages = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )
name |
Character string, the target name. |
script |
Path to the Julia script to run (required). Accepts a literal path, a |
pre_script |
Optional path to an R script run before the Julia script. See |
post_script |
Optional path to an R script run after the Julia script. See |
inputs |
Named character vector (or list) mapping the name seen inside the step (in the R environment and, after the hand-off, in the foreign session) to the name of an upstream target, e.g. |
output |
Output mode: |
retrieve |
Optional character vector of foreign-session variable names to return when no |
files |
Optional character vector of file paths to return when no |
julia_version |
Optional Julia version to select (e.g. |
julia_home, julia_project, julia_packages
|
Julia environment selection, forwarded to |
pattern |
Optional targets dynamic-branching pattern as a language object (e.g. |
packages, library
|
Character vectors of R packages (and library paths) to load for the target, forwarded to |
deps, string
|
Advanced |
format, repository, iteration
|
Storage/iteration settings forwarded to |
error, memory, garbage_collection, deployment, priority, resources, storage, retrieval, cue, description
|
Standard |
All targets::tar_target_raw() arguments are forwarded unchanged, so dynamic branching (pattern), storage format, deployment, resources, cue, etc. all work as usual. Upstream targets are wired in through inputs, which become dependencies (and are sliced under dynamic branching).
A targets target object.
Every script argument (script, and pre_script / post_script where the constructor has them) accepts the same three forms. The choice is not cosmetic: it decides whether editing the code re-runs the target.
e.g. script = "py/step.py". The file is read when the step runs, but it is not tracked, so editing it does not invalidate the target: targets will happily reuse a stale result until some other dependency changes. Simplest form, and a reasonable default once a script has settled.
tar_target_path() referencee.g. script = tar_target_path("step_py"), naming an upstream tar_target(step_py, "py/step.py", format = "file"). The file becomes a real targets dependency, so editing it does invalidate this target and the step re-runs. This is what you want while a script is still changing, and the recommended form for reproducible pipelines.
tar_code()
e.g. script = tar_code("result = sum(x)"). The code lives in _targets.R rather than in a file, and is embedded in the target's command, so targets hashes it and editing it does invalidate the target. A character string carries foreign source (Python, Julia, Rust, C++) or R source; an R { ... } block carries inline R and is accepted only by pre_script / post_script, never by the foreign script.
Mixing forms in one call is fine: a tracked script with a literal post_script, inline code for one and a file for another, and so on. See vignette("scripts") for worked examples of all three and guidance on choosing.
tar_target_jl(), run_jl_step(), tar_target_py_raw()
# Building a target does not run it, so these examples need no Julia. # scripts/sum.jl (uses the `using Statistics` julia_packages requests): # result = mean(x) # scripts/post.R: # jl_get("result") tarpolyglot::tar_target_jl_raw( name = "jl_sum", script = "scripts/sum.jl", inputs = c(x = "prepared_x"), post_script = "scripts/post.R", julia_packages = "Statistics" ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_jl_raw( name = "demo_literal", script = "jl/step.jl", retrieve = "result" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_jl, "jl/step.jl", format = "file"), tarpolyglot::tar_target_jl_raw( name = "demo_tracked", script = tarpolyglot::tar_target_path("step_jl"), retrieve = "result" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_jl_raw( name = "demo_inline", script = tarpolyglot::tar_code("result = 1 + 1"), post_script = tarpolyglot::tar_code({ jl_get("result") }) ) # Tracking a helper file the script includes. Point `inputs` at a # format = "file" target so editing the helper also re-runs the step; # `inputs` takes the *target* name, not the path. Julia resolves a # relative include() against the including file's own directory, so make # the path absolute. jl/step.jl is then: # include(helper_path) # result = sum(myscale(x)) list( targets::tar_target(helper_file, "jl/helper.jl", format = "file"), tarpolyglot::tar_target_jl_raw( name = "demo_helper", script = "jl/step.jl", inputs = c(x = "prepared_x", helper_path = "helper_file"), pre_script = tarpolyglot::tar_code({ to_jl <- list(x = x, helper_path = normalizePath(helper_path, winslash = "/")) }), retrieve = "result" ) )# Building a target does not run it, so these examples need no Julia. # scripts/sum.jl (uses the `using Statistics` julia_packages requests): # result = mean(x) # scripts/post.R: # jl_get("result") tarpolyglot::tar_target_jl_raw( name = "jl_sum", script = "scripts/sum.jl", inputs = c(x = "prepared_x"), post_script = "scripts/post.R", julia_packages = "Statistics" ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_jl_raw( name = "demo_literal", script = "jl/step.jl", retrieve = "result" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_jl, "jl/step.jl", format = "file"), tarpolyglot::tar_target_jl_raw( name = "demo_tracked", script = tarpolyglot::tar_target_path("step_jl"), retrieve = "result" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_jl_raw( name = "demo_inline", script = tarpolyglot::tar_code("result = 1 + 1"), post_script = tarpolyglot::tar_code({ jl_get("result") }) ) # Tracking a helper file the script includes. Point `inputs` at a # format = "file" target so editing the helper also re-runs the step; # `inputs` takes the *target* name, not the path. Julia resolves a # relative include() against the including file's own directory, so make # the path absolute. jl/step.jl is then: # include(helper_path) # result = sum(myscale(x)) list( targets::tar_target(helper_file, "jl/helper.jl", format = "file"), tarpolyglot::tar_target_jl_raw( name = "demo_helper", script = "jl/step.jl", inputs = c(x = "prepared_x", helper_path = "helper_file"), pre_script = tarpolyglot::tar_code({ to_jl <- list(x = x, helper_path = normalizePath(helper_path, winslash = "/")) }), retrieve = "result" ) )
targets dependencyUse as the script, pre_script, or post_script argument of tar_target_py()/tar_target_jl()/tar_target_rs() (and their _raw forms) instead of a literal path string, to make that step re-run whenever the script file changes. name is the name of an upstream targets target (typically one created with format = "file" tracking the script file), and its value (the file path) is substituted in when the pipeline runs.
tar_target_path(name)tar_target_path(name)
name |
Character string, the name of an upstream target whose value is the script's file path (e.g. a |
This mirrors how inputs = c(x = "some_target") already wires an upstream target in by name: the target's name is given as a string, and the constructor turns it into a real dependency. A plain string passed directly as script/pre_script/post_script keeps meaning what it always has (an untracked literal path), so existing pipelines are unaffected.
An object marking name for dependency-wiring by the tar_target_* constructors.
tar_target_py(), tar_target_jl(), tar_target_rs()
# Building a target does not run it, so this example needs no Python. # python/fit_step.py: # result = sum(x) # scripts/pre.R: # to_py <- list(x = x) list( targets::tar_target(fit_pyscript, "python/fit_step.py", format = "file"), tar_target_py( name = fit, script = tar_target_path("fit_pyscript"), # re-runs when the file changes pre_script = "scripts/pre.R", # untracked literal path inputs = c(x = "prepared_x"), retrieve = "result" ) )# Building a target does not run it, so this example needs no Python. # python/fit_step.py: # result = sum(x) # scripts/pre.R: # to_py <- list(x = x) list( targets::tar_target(fit_pyscript, "python/fit_step.py", format = "file"), tar_target_py( name = fit, script = tar_target_path("fit_pyscript"), # re-runs when the file changes pre_script = "scripts/pre.R", # untracked literal path inputs = c(x = "prepared_x"), retrieve = "result" ) )
Non-standard-evaluation constructor mirroring targets::tar_target(): pass a bare name and an unquoted pattern, for direct use in _targets.R. It quotes those and delegates to tar_target_py_raw(). See that function and run_py_step() for the full argument reference and the pre/post-script contract. The Julia twin is tar_target_jl().
tar_target_py( name, script, pre_script = NULL, post_script = NULL, inputs = NULL, output = "object", retrieve = NULL, files = NULL, python_version = NULL, env = NULL, env_manager = "system", python = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )tar_target_py( name, script, pre_script = NULL, post_script = NULL, inputs = NULL, output = "object", retrieve = NULL, files = NULL, python_version = NULL, env = NULL, env_manager = "system", python = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )
name |
Symbol, the target name (unquoted). |
script |
Path to the Python script to run (required). Accepts a literal path, a |
pre_script |
Optional path to an R script run before the Python script. See |
post_script |
Optional path to an R script run after the Python script. See |
inputs |
Named character vector (or list) mapping the name seen inside the step (in the R environment and, after the hand-off, in the foreign session) to the name of an upstream target, e.g. |
output |
Output mode: |
retrieve |
Optional character vector of foreign-session variable names to return when no |
files |
Optional character vector of file paths to return when no |
python_version |
Optional Python version to select (e.g. |
env, env_manager, python
|
Python environment selection: the reproducible alternatives to |
pattern |
Optional dynamic-branching pattern, unquoted (e.g. |
packages, library
|
Character vectors of R packages (and library paths) to load for the target, forwarded to |
deps, string
|
Advanced |
format, repository, iteration
|
Storage/iteration settings forwarded to |
error, memory, garbage_collection, deployment, priority, resources, storage, retrieval, cue, description
|
Standard |
A targets target object.
Every script argument (script, and pre_script / post_script where the constructor has them) accepts the same three forms. The choice is not cosmetic: it decides whether editing the code re-runs the target.
e.g. script = "py/step.py". The file is read when the step runs, but it is not tracked, so editing it does not invalidate the target: targets will happily reuse a stale result until some other dependency changes. Simplest form, and a reasonable default once a script has settled.
tar_target_path() referencee.g. script = tar_target_path("step_py"), naming an upstream tar_target(step_py, "py/step.py", format = "file"). The file becomes a real targets dependency, so editing it does invalidate this target and the step re-runs. This is what you want while a script is still changing, and the recommended form for reproducible pipelines.
tar_code()
e.g. script = tar_code("result = sum(x)"). The code lives in _targets.R rather than in a file, and is embedded in the target's command, so targets hashes it and editing it does invalidate the target. A character string carries foreign source (Python, Julia, Rust, C++) or R source; an R { ... } block carries inline R and is accepted only by pre_script / post_script, never by the foreign script.
Mixing forms in one call is fine: a tracked script with a literal post_script, inline code for one and a file for another, and so on. See vignette("scripts") for worked examples of all three and guidance on choosing.
tar_target_py_raw(), run_py_step(), tar_target_jl()
# Building a target does not run it, so these examples need no Python. # Inside _targets.R: # scripts/sum.py: # result = sum(x) # scripts/post.R: # py$result list( tarpolyglot::tar_target_py( name = py_sum, script = "scripts/sum.py", inputs = c(x = "prepared_x"), post_script = "scripts/post.R" ) ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_py( name = demo_literal, script = "py/step.py", retrieve = "result" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_py, "py/step.py", format = "file"), tarpolyglot::tar_target_py( name = demo_tracked, script = tarpolyglot::tar_target_path("step_py"), retrieve = "result" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_py( name = demo_inline, script = tarpolyglot::tar_code("result = 1 + 1"), post_script = tarpolyglot::tar_code({ py_get("result") }) ) # Tracking a helper module the script imports. Point `inputs` at a # format = "file" target so editing the helper also re-runs the step; # `inputs` takes the *target* name, not the path. py/step.py then loads # the helper from the bound path rather than a hard-coded one: # import os, sys # sys.path.insert(0, os.path.dirname(helper_path)) # import helper # result = sum(helper.scale(x)) list( targets::tar_target(helper_file, "py/helper.py", format = "file"), tarpolyglot::tar_target_py( name = demo_helper, script = "py/step.py", inputs = c(x = "prepared_x", helper_path = "helper_file"), pre_script = tarpolyglot::tar_code({ to_py <- list(x = x, helper_path = helper_path) }), retrieve = "result" ) )# Building a target does not run it, so these examples need no Python. # Inside _targets.R: # scripts/sum.py: # result = sum(x) # scripts/post.R: # py$result list( tarpolyglot::tar_target_py( name = py_sum, script = "scripts/sum.py", inputs = c(x = "prepared_x"), post_script = "scripts/post.R" ) ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_py( name = demo_literal, script = "py/step.py", retrieve = "result" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_py, "py/step.py", format = "file"), tarpolyglot::tar_target_py( name = demo_tracked, script = tarpolyglot::tar_target_path("step_py"), retrieve = "result" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_py( name = demo_inline, script = tarpolyglot::tar_code("result = 1 + 1"), post_script = tarpolyglot::tar_code({ py_get("result") }) ) # Tracking a helper module the script imports. Point `inputs` at a # format = "file" target so editing the helper also re-runs the step; # `inputs` takes the *target* name, not the path. py/step.py then loads # the helper from the bound path rather than a hard-coded one: # import os, sys # sys.path.insert(0, os.path.dirname(helper_path)) # import helper # result = sum(helper.scale(x)) list( targets::tar_target(helper_file, "py/helper.py", format = "file"), tarpolyglot::tar_target_py( name = demo_helper, script = "py/step.py", inputs = c(x = "prepared_x", helper_path = "helper_file"), pre_script = tarpolyglot::tar_code({ to_py <- list(x = x, helper_path = helper_path) }), retrieve = "result" ) )
Character-based constructor mirroring targets::tar_target_raw(): name is a string and it is meant for use inside targets factories. Returns a single targets target whose command runs an optional R pre-script, script (via reticulate), and an optional R post-script, then returns a converted R object or a character vector of files. See run_py_step() for the pre/post-script contract (the to_py hand-off and the py / py_get helpers). For direct use in _targets.R, see tar_target_py(). The Julia twin is tar_target_jl_raw().
tar_target_py_raw( name, script, pre_script = NULL, post_script = NULL, inputs = NULL, output = "object", retrieve = NULL, files = NULL, python_version = NULL, env = NULL, env_manager = "system", python = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )tar_target_py_raw( name, script, pre_script = NULL, post_script = NULL, inputs = NULL, output = "object", retrieve = NULL, files = NULL, python_version = NULL, env = NULL, env_manager = "system", python = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )
name |
Character string, the target name. |
script |
Path to the Python script to run (required). Accepts a literal path, a |
pre_script |
Optional path to an R script run before the Python script. See |
post_script |
Optional path to an R script run after the Python script. See |
inputs |
Named character vector (or list) mapping the name seen inside the step (in the R environment and, after the hand-off, in the foreign session) to the name of an upstream target, e.g. |
output |
Output mode: |
retrieve |
Optional character vector of foreign-session variable names to return when no |
files |
Optional character vector of file paths to return when no |
python_version |
Optional Python version to select (e.g. |
env, env_manager, python
|
Python environment selection: the reproducible alternatives to |
pattern |
Optional targets dynamic-branching pattern as a language object (e.g. |
packages, library
|
Character vectors of R packages (and library paths) to load for the target, forwarded to |
deps, string
|
Advanced |
format, repository, iteration
|
Storage/iteration settings forwarded to |
error, memory, garbage_collection, deployment, priority, resources, storage, retrieval, cue, description
|
Standard |
All targets::tar_target_raw() arguments are forwarded unchanged, so dynamic branching (pattern), storage format, deployment, resources, cue, etc. all work as usual. Upstream targets are wired in through inputs, which become dependencies (and are sliced under dynamic branching).
The interpreter/environment selection arguments (python, env, env_manager, python_version) are forwarded to run_py_step(), which documents them (they are alternatives: normally set only one; precedence python > env/env_manager > python_version > none). See also vignette("python") for a decision guide with examples.
A targets target object.
Every script argument (script, and pre_script / post_script where the constructor has them) accepts the same three forms. The choice is not cosmetic: it decides whether editing the code re-runs the target.
e.g. script = "py/step.py". The file is read when the step runs, but it is not tracked, so editing it does not invalidate the target: targets will happily reuse a stale result until some other dependency changes. Simplest form, and a reasonable default once a script has settled.
tar_target_path() referencee.g. script = tar_target_path("step_py"), naming an upstream tar_target(step_py, "py/step.py", format = "file"). The file becomes a real targets dependency, so editing it does invalidate this target and the step re-runs. This is what you want while a script is still changing, and the recommended form for reproducible pipelines.
tar_code()
e.g. script = tar_code("result = sum(x)"). The code lives in _targets.R rather than in a file, and is embedded in the target's command, so targets hashes it and editing it does invalidate the target. A character string carries foreign source (Python, Julia, Rust, C++) or R source; an R { ... } block carries inline R and is accepted only by pre_script / post_script, never by the foreign script.
Mixing forms in one call is fine: a tracked script with a literal post_script, inline code for one and a file for another, and so on. See vignette("scripts") for worked examples of all three and guidance on choosing.
tar_target_py(), run_py_step(), tar_target_jl_raw()
# Building a target does not run it, so these examples need no Python. # Inside a targets factory: # scripts/pre.R: # to_py <- list(x = x) # scripts/sum.py: # result = sum(x) # scripts/post.R: # py$result tarpolyglot::tar_target_py_raw( name = "py_sum", script = "scripts/sum.py", inputs = c(x = "prepared_x"), pre_script = "scripts/pre.R", post_script = "scripts/post.R" ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_py_raw( name = "demo_literal", script = "py/step.py", retrieve = "result" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_py, "py/step.py", format = "file"), tarpolyglot::tar_target_py_raw( name = "demo_tracked", script = tarpolyglot::tar_target_path("step_py"), retrieve = "result" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_py_raw( name = "demo_inline", script = tarpolyglot::tar_code("result = 1 + 1"), post_script = tarpolyglot::tar_code({ py_get("result") }) ) # Tracking a helper module the script imports. Point `inputs` at a # format = "file" target so editing the helper also re-runs the step; # `inputs` takes the *target* name, not the path. py/step.py then loads # the helper from the bound path rather than a hard-coded one: # import os, sys # sys.path.insert(0, os.path.dirname(helper_path)) # import helper # result = sum(helper.scale(x)) list( targets::tar_target(helper_file, "py/helper.py", format = "file"), tarpolyglot::tar_target_py_raw( name = "demo_helper", script = "py/step.py", inputs = c(x = "prepared_x", helper_path = "helper_file"), pre_script = tarpolyglot::tar_code({ to_py <- list(x = x, helper_path = helper_path) }), retrieve = "result" ) )# Building a target does not run it, so these examples need no Python. # Inside a targets factory: # scripts/pre.R: # to_py <- list(x = x) # scripts/sum.py: # result = sum(x) # scripts/post.R: # py$result tarpolyglot::tar_target_py_raw( name = "py_sum", script = "scripts/sum.py", inputs = c(x = "prepared_x"), pre_script = "scripts/pre.R", post_script = "scripts/post.R" ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_py_raw( name = "demo_literal", script = "py/step.py", retrieve = "result" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_py, "py/step.py", format = "file"), tarpolyglot::tar_target_py_raw( name = "demo_tracked", script = tarpolyglot::tar_target_path("step_py"), retrieve = "result" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_py_raw( name = "demo_inline", script = tarpolyglot::tar_code("result = 1 + 1"), post_script = tarpolyglot::tar_code({ py_get("result") }) ) # Tracking a helper module the script imports. Point `inputs` at a # format = "file" target so editing the helper also re-runs the step; # `inputs` takes the *target* name, not the path. py/step.py then loads # the helper from the bound path rather than a hard-coded one: # import os, sys # sys.path.insert(0, os.path.dirname(helper_path)) # import helper # result = sum(helper.scale(x)) list( targets::tar_target(helper_file, "py/helper.py", format = "file"), tarpolyglot::tar_target_py_raw( name = "demo_helper", script = "py/step.py", inputs = c(x = "prepared_x", helper_path = "helper_file"), pre_script = tarpolyglot::tar_code({ to_py <- list(x = x, helper_path = helper_path) }), retrieve = "result" ) )
Non-standard-evaluation constructor mirroring targets::tar_target() for Rust: pass a bare name and unquoted pattern, for direct use in _targets.R. Compiles the #[extendr] functions in script with rextendr::rust_source() and calls them from the R post_script. Delegates to tar_target_rs_raw(); see it and run_rs_step() for the full reference. The Python/Julia twins are tar_target_py() / tar_target_jl().
tar_target_rs( name, script, post_script = NULL, inputs = NULL, output = "object", files = NULL, dependencies = NULL, features = NULL, profile = NULL, toolchain = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )tar_target_rs( name, script, post_script = NULL, inputs = NULL, output = "object", files = NULL, dependencies = NULL, features = NULL, profile = NULL, toolchain = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )
name |
Symbol, the target name (unquoted). |
script |
Path to the Rust script with |
post_script |
Path to an R script run after compilation, where the compiled functions and |
inputs |
Named character vector (or list) mapping the name seen inside the step (in the R environment and, after the hand-off, in the foreign session) to the name of an upstream target, e.g. |
output |
Output mode: |
files |
Optional character vector of file paths to return when no |
dependencies, features, profile
|
Passed to |
toolchain |
Optional rustup toolchain (e.g. |
pattern |
Optional branching pattern as described in the targets package documentation, unquoted (e.g. |
packages, library
|
Character vectors of R packages (and library paths) to load for the target, forwarded to |
deps, string
|
Advanced |
format, repository, iteration
|
Storage/iteration settings forwarded to |
error, memory, garbage_collection, deployment, priority, resources, storage, retrieval, cue, description
|
Standard |
A targets target object. When pattern uses tarpolyglot_map() it is instead a list of two targets: the <name>_rust_lib compile target and the branched <name> target.
Every script argument (script, and pre_script / post_script where the constructor has them) accepts the same three forms. The choice is not cosmetic: it decides whether editing the code re-runs the target.
e.g. script = "py/step.py". The file is read when the step runs, but it is not tracked, so editing it does not invalidate the target: targets will happily reuse a stale result until some other dependency changes. Simplest form, and a reasonable default once a script has settled.
tar_target_path() referencee.g. script = tar_target_path("step_py"), naming an upstream tar_target(step_py, "py/step.py", format = "file"). The file becomes a real targets dependency, so editing it does invalidate this target and the step re-runs. This is what you want while a script is still changing, and the recommended form for reproducible pipelines.
tar_code()
e.g. script = tar_code("result = sum(x)"). The code lives in _targets.R rather than in a file, and is embedded in the target's command, so targets hashes it and editing it does invalidate the target. A character string carries foreign source (Python, Julia, Rust, C++) or R source; an R { ... } block carries inline R and is accepted only by pre_script / post_script, never by the foreign script.
Mixing forms in one call is fine: a tracked script with a literal post_script, inline code for one and a file for another, and so on. See vignette("scripts") for worked examples of all three and guidance on choosing.
tar_target_rs_raw(), tarpolyglot_map(), run_rs_step(), tar_target_py(), tar_target_jl()
# Building a target does not run it, so these examples need no Rust toolchain. # scripts/square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # scripts/post.R: # square(x) list( tarpolyglot::tar_target_rs( name = rs_square, script = "scripts/square.rs", inputs = c(x = "value"), post_script = "scripts/post.R" ) ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_rs( name = demo_literal, script = "rs/step.rs", post_script = "R/post.R" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_rs, "rs/step.rs", format = "file"), tarpolyglot::tar_target_rs( name = demo_tracked, script = tarpolyglot::tar_target_path("step_rs"), post_script = "R/post.R" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_rs( name = demo_inline, script = tarpolyglot::tar_code("#[extendr] fn one() -> f64 { 1.0 }"), post_script = tarpolyglot::tar_code({ one() }) )# Building a target does not run it, so these examples need no Rust toolchain. # scripts/square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # scripts/post.R: # square(x) list( tarpolyglot::tar_target_rs( name = rs_square, script = "scripts/square.rs", inputs = c(x = "value"), post_script = "scripts/post.R" ) ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_rs( name = demo_literal, script = "rs/step.rs", post_script = "R/post.R" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_rs, "rs/step.rs", format = "file"), tarpolyglot::tar_target_rs( name = demo_tracked, script = tarpolyglot::tar_target_path("step_rs"), post_script = "R/post.R" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_rs( name = demo_inline, script = tarpolyglot::tar_code("#[extendr] fn one() -> f64 { 1.0 }"), post_script = tarpolyglot::tar_code({ one() }) )
Character-based constructor mirroring targets::tar_target_raw() for Rust, for use inside targets factories. Returns a single targets target whose command compiles the #[extendr] functions in script with rextendr::rust_source() and then evaluates an R post-script that calls those functions (with the upstream inputs in scope) and returns the value. See run_rs_step() for the contract. For direct use in _targets.R, see tar_target_rs().
tar_target_rs_raw( name, script, post_script = NULL, inputs = NULL, output = "object", files = NULL, dependencies = NULL, features = NULL, profile = NULL, toolchain = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )tar_target_rs_raw( name, script, post_script = NULL, inputs = NULL, output = "object", files = NULL, dependencies = NULL, features = NULL, profile = NULL, toolchain = NULL, pattern = NULL, packages = targets::tar_option_get("packages"), library = targets::tar_option_get("library"), deps = NULL, string = NULL, format = NULL, repository = targets::tar_option_get("repository"), iteration = targets::tar_option_get("iteration"), error = targets::tar_option_get("error"), memory = targets::tar_option_get("memory"), garbage_collection = isTRUE(targets::tar_option_get("garbage_collection")), deployment = targets::tar_option_get("deployment"), priority = targets::tar_option_get("priority"), resources = targets::tar_option_get("resources"), storage = targets::tar_option_get("storage"), retrieval = targets::tar_option_get("retrieval"), cue = targets::tar_option_get("cue"), description = targets::tar_option_get("description") )
name |
Character string, the target name. |
script |
Path to the Rust script with |
post_script |
Path to an R script run after compilation, where the compiled functions and |
inputs |
Named character vector (or list) mapping the name seen inside the step (in the R environment and, after the hand-off, in the foreign session) to the name of an upstream target, e.g. |
output |
Output mode: |
files |
Optional character vector of file paths to return when no |
dependencies, features, profile
|
Passed to |
toolchain |
Optional rustup toolchain (e.g. |
pattern |
Optional branching pattern as described in the targets package documentation, as a language object (e.g. |
packages, library
|
Character vectors of R packages (and library paths) to load for the target, forwarded to |
deps, string
|
Advanced |
format, repository, iteration
|
Storage/iteration settings forwarded to |
error, memory, garbage_collection, deployment, priority, resources, storage, retrieval, cue, description
|
Standard |
Unlike Python/Julia there is no pre-script for Rust: inputs are used directly in the post-script alongside the compiled functions. A Rust toolchain and cargo are required; on Windows use the GNU toolchain (see vignette("rust")).
Under dynamic branching, pattern = map(...) recompiles the crate in every branch (Rust has no live interpreter to reuse). Passing a tarpolyglot pattern helper instead (tarpolyglot_map(), tarpolyglot_cross(), tarpolyglot_slice(), tarpolyglot_head(), tarpolyglot_tail(), tarpolyglot_sample()) compiles the crate once in a companion target named <name>_rust_lib and reuses it across all branches; the constructor then returns both targets as a list. See tarpolyglot_map().
A targets target object. When pattern uses tarpolyglot_map() it is instead a list of two targets: the <name>_rust_lib compile target and the branched <name> target.
Every script argument (script, and pre_script / post_script where the constructor has them) accepts the same three forms. The choice is not cosmetic: it decides whether editing the code re-runs the target.
e.g. script = "py/step.py". The file is read when the step runs, but it is not tracked, so editing it does not invalidate the target: targets will happily reuse a stale result until some other dependency changes. Simplest form, and a reasonable default once a script has settled.
tar_target_path() referencee.g. script = tar_target_path("step_py"), naming an upstream tar_target(step_py, "py/step.py", format = "file"). The file becomes a real targets dependency, so editing it does invalidate this target and the step re-runs. This is what you want while a script is still changing, and the recommended form for reproducible pipelines.
tar_code()
e.g. script = tar_code("result = sum(x)"). The code lives in _targets.R rather than in a file, and is embedded in the target's command, so targets hashes it and editing it does invalidate the target. A character string carries foreign source (Python, Julia, Rust, C++) or R source; an R { ... } block carries inline R and is accepted only by pre_script / post_script, never by the foreign script.
Mixing forms in one call is fine: a tracked script with a literal post_script, inline code for one and a file for another, and so on. See vignette("scripts") for worked examples of all three and guidance on choosing.
tar_target_rs(), tarpolyglot_map(), run_rs_step(), tar_target_py_raw(), tar_target_jl_raw()
# Building a target does not run it, so these examples need no Rust toolchain. # scripts/square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # scripts/post.R: # square(x) tarpolyglot::tar_target_rs_raw( name = "rs_square", script = "scripts/square.rs", inputs = c(x = "value"), post_script = "scripts/post.R" ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_rs_raw( name = "demo_literal", script = "rs/step.rs", post_script = "R/post.R" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_rs, "rs/step.rs", format = "file"), tarpolyglot::tar_target_rs_raw( name = "demo_tracked", script = tarpolyglot::tar_target_path("step_rs"), post_script = "R/post.R" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_rs_raw( name = "demo_inline", script = tarpolyglot::tar_code("#[extendr] fn one() -> f64 { 1.0 }"), post_script = tarpolyglot::tar_code({ one() }) )# Building a target does not run it, so these examples need no Rust toolchain. # scripts/square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # scripts/post.R: # square(x) tarpolyglot::tar_target_rs_raw( name = "rs_square", script = "scripts/square.rs", inputs = c(x = "value"), post_script = "scripts/post.R" ) # The three ways to supply a script (see the "Script options" section): # 1. Literal path: untracked, editing the file does NOT re-run the step. tarpolyglot::tar_target_rs_raw( name = "demo_literal", script = "rs/step.rs", post_script = "R/post.R" ) # 2. tar_target_path(): tracked, editing the file DOES re-run the step. list( targets::tar_target(step_rs, "rs/step.rs", format = "file"), tarpolyglot::tar_target_rs_raw( name = "demo_tracked", script = tarpolyglot::tar_target_path("step_rs"), post_script = "R/post.R" ) ) # 3. tar_code(): inline, editing the code DOES re-run the step. A string # carries foreign source; an R { } block carries inline R. tarpolyglot::tar_target_rs_raw( name = "demo_inline", script = tarpolyglot::tar_code("#[extendr] fn one() -> f64 { 1.0 }"), post_script = tarpolyglot::tar_code({ one() }) )
A drop-in replacement for the targets targets::tar_target() pattern helper cross(), for use unquoted in the pattern argument of a tarpolyglot constructor. Like tarpolyglot_map(), on tar_target_rs() it compiles the extendr crate once in a companion <name>_rust_lib target and reuses it across every branch (instead of recompiling per branch); on tar_target_py() / tar_target_jl() it is exactly cross(). See tarpolyglot_map() for the full explanation and the compile-once mechanics.
tarpolyglot_cross(...)tarpolyglot_cross(...)
... |
Upstream targets to cross (all combinations), with the same meaning as in the targets |
This function is a marker consumed by the tarpolyglot constructors and is not meant to be evaluated on its own; calling it directly raises an error.
The tarpolyglot_*() pattern helpers work only inside the pattern argument of the tarpolyglot constructors (tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl(), and their _raw() forms), which rewrite them to the plain targets pattern before building the target. Used directly in a plain targets::tar_target() or targets::tar_target_raw() they raise an error such as invalid dynamic branching pattern ... Illegal symbols found: tarpolyglot_map, because targets validates a pattern against its own fixed set of pattern functions and does not know these helpers. This cannot be fixed from tarpolyglot: targets looks its pattern functions up in a locked internal environment, so teaching it a new one would require modifying the targets package itself. In a plain targets target (which has no foreign code to compile, so nothing to gain) use the native map() / cross() / slice() / head() / tail() / sample() instead.
The other pattern helpers: tarpolyglot_map(), tarpolyglot_slice(), tarpolyglot_head(), tarpolyglot_tail(), tarpolyglot_sample(). The constructors that accept them: tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl()
# square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # post.R: # square(x) tarpolyglot::tar_target_rs( name = rs_grid, script = "square.rs", inputs = c(x = "a", y = "b"), post_script = "post.R", pattern = tarpolyglot_cross(a, b) )# square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # post.R: # square(x) tarpolyglot::tar_target_rs( name = rs_grid, script = "square.rs", inputs = c(x = "a", y = "b"), post_script = "post.R", pattern = tarpolyglot_cross(a, b) )
A drop-in replacement for the targets targets::tar_target() pattern helper head(), for use unquoted in the pattern argument of a tarpolyglot constructor. Like tarpolyglot_map(), on tar_target_rs() it compiles the extendr crate once in a companion <name>_rust_lib target and reuses it across the kept branches; on tar_target_py() / tar_target_jl() it is exactly head(). See tarpolyglot_map() for the full explanation and the compile-once mechanics.
tarpolyglot_head(..., n)tarpolyglot_head(..., n)
... |
Upstream target(s) to branch over, with the same meaning as in the targets |
n |
Number of branches to keep from the start, as in the targets |
This function is a marker consumed by the tarpolyglot constructors and is not meant to be evaluated on its own; calling it directly raises an error.
The tarpolyglot_*() pattern helpers work only inside the pattern argument of the tarpolyglot constructors (tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl(), and their _raw() forms), which rewrite them to the plain targets pattern before building the target. Used directly in a plain targets::tar_target() or targets::tar_target_raw() they raise an error such as invalid dynamic branching pattern ... Illegal symbols found: tarpolyglot_map, because targets validates a pattern against its own fixed set of pattern functions and does not know these helpers. This cannot be fixed from tarpolyglot: targets looks its pattern functions up in a locked internal environment, so teaching it a new one would require modifying the targets package itself. In a plain targets target (which has no foreign code to compile, so nothing to gain) use the native map() / cross() / slice() / head() / tail() / sample() instead.
The other pattern helpers: tarpolyglot_map(), tarpolyglot_cross(), tarpolyglot_slice(), tarpolyglot_tail(), tarpolyglot_sample(). The constructors that accept them: tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl()
# square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # post.R: # square(x) tarpolyglot::tar_target_rs( name = rs_first, script = "square.rs", inputs = c(x = "vals"), post_script = "post.R", pattern = tarpolyglot_head(vals, n = 2) )# square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # post.R: # square(x) tarpolyglot::tar_target_rs( name = rs_first, script = "square.rs", inputs = c(x = "vals"), post_script = "post.R", pattern = tarpolyglot_head(vals, n = 2) )
A drop-in replacement for the targets targets::tar_target() pattern helper map(), for use unquoted in the pattern argument of a tarpolyglot constructor (tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl(), and their _raw forms).
tarpolyglot_map(...)tarpolyglot_map(...)
... |
Upstream targets to map over in parallel, exactly as in the targets |
On tar_target_rs() and tar_target_cpp() it changes how the branches are built: the crate/library is compiled once in a companion target named <name>_rust_lib / <name>_cpp_lib, and every branch reuses that compiled library instead of recompiling. Recompiling per branch is otherwise the default, because Rust and C++ have no live interpreter (contrast Python/Julia, whose interpreter is simply reused). With three branches this turns roughly 3 x compile into 1 x compile + 3 x (near-instant reload).
On tar_target_py() and tar_target_jl() there is nothing to compile, so tarpolyglot_map() is exactly map(): it is provided so the same pipeline code can branch every language uniformly.
Use it wherever you would write map(): pattern = tarpolyglot_map(x). The arguments are upstream target names to iterate over in parallel, with the same meaning as targets::tar_target()'s map().
This function is a marker consumed by the tarpolyglot constructors and is not meant to be evaluated on its own; calling it directly raises an error.
The tarpolyglot_*() pattern helpers work only inside the pattern argument of the tarpolyglot constructors (tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl(), and their _raw() forms), which rewrite them to the plain targets pattern before building the target. Used directly in a plain targets::tar_target() or targets::tar_target_raw() they raise an error such as invalid dynamic branching pattern ... Illegal symbols found: tarpolyglot_map, because targets validates a pattern against its own fixed set of pattern functions and does not know these helpers. This cannot be fixed from tarpolyglot: targets looks its pattern functions up in a locked internal environment, so teaching it a new one would require modifying the targets package itself. In a plain targets target (which has no foreign code to compile, so nothing to gain) use the native map() / cross() / slice() / head() / tail() / sample() instead.
The other pattern helpers: tarpolyglot_cross(), tarpolyglot_slice(), tarpolyglot_head(), tarpolyglot_tail(), tarpolyglot_sample(). The constructors that accept them: tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl()
# rs/square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # R/post_square.R: # square(x) list( targets::tar_target(vals, c(10, 20, 30)), # Rust: compiles rs/square.rs once in `rs_branch_rust_lib`, then squares # each branch value reusing that compiled library. tarpolyglot::tar_target_rs( name = rs_branch, script = "rs/square.rs", inputs = c(x = "vals"), post_script = "R/post_square.R", pattern = tarpolyglot_map(vals) ) )# rs/square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # R/post_square.R: # square(x) list( targets::tar_target(vals, c(10, 20, 30)), # Rust: compiles rs/square.rs once in `rs_branch_rust_lib`, then squares # each branch value reusing that compiled library. tarpolyglot::tar_target_rs( name = rs_branch, script = "rs/square.rs", inputs = c(x = "vals"), post_script = "R/post_square.R", pattern = tarpolyglot_map(vals) ) )
A drop-in replacement for the targets targets::tar_target() pattern helper sample(), for use unquoted in the pattern argument of a tarpolyglot constructor. Like tarpolyglot_map(), on tar_target_rs() it compiles the extendr crate once in a companion <name>_rust_lib target and reuses it across the sampled branches; on tar_target_py() / tar_target_jl() it is exactly sample(). See tarpolyglot_map() for the full explanation and the compile-once mechanics.
tarpolyglot_sample(..., n)tarpolyglot_sample(..., n)
... |
Upstream target(s) to branch over, with the same meaning as in the targets |
n |
Number of branches to sample at random, as in the targets |
This function is a marker consumed by the tarpolyglot constructors and is not meant to be evaluated on its own; calling it directly raises an error.
The tarpolyglot_*() pattern helpers work only inside the pattern argument of the tarpolyglot constructors (tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl(), and their _raw() forms), which rewrite them to the plain targets pattern before building the target. Used directly in a plain targets::tar_target() or targets::tar_target_raw() they raise an error such as invalid dynamic branching pattern ... Illegal symbols found: tarpolyglot_map, because targets validates a pattern against its own fixed set of pattern functions and does not know these helpers. This cannot be fixed from tarpolyglot: targets looks its pattern functions up in a locked internal environment, so teaching it a new one would require modifying the targets package itself. In a plain targets target (which has no foreign code to compile, so nothing to gain) use the native map() / cross() / slice() / head() / tail() / sample() instead.
The other pattern helpers: tarpolyglot_map(), tarpolyglot_cross(), tarpolyglot_slice(), tarpolyglot_head(), tarpolyglot_tail(). The constructors that accept them: tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl()
# square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # post.R: # square(x) tarpolyglot::tar_target_rs( name = rs_rand, script = "square.rs", inputs = c(x = "vals"), post_script = "post.R", pattern = tarpolyglot_sample(vals, n = 2) )# square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # post.R: # square(x) tarpolyglot::tar_target_rs( name = rs_rand, script = "square.rs", inputs = c(x = "vals"), post_script = "post.R", pattern = tarpolyglot_sample(vals, n = 2) )
A drop-in replacement for the targets targets::tar_target() pattern helper slice(), for use unquoted in the pattern argument of a tarpolyglot constructor. Like tarpolyglot_map(), on tar_target_rs() it compiles the extendr crate once in a companion <name>_rust_lib target and reuses it across the selected branches; on tar_target_py() / tar_target_jl() it is exactly slice(). See tarpolyglot_map() for the full explanation and the compile-once mechanics.
tarpolyglot_slice(..., index)tarpolyglot_slice(..., index)
... |
Upstream target(s) to branch over, with the same meaning as in the targets |
index |
Integer vector of branch indices to keep, as in the targets |
This function is a marker consumed by the tarpolyglot constructors and is not meant to be evaluated on its own; calling it directly raises an error.
The tarpolyglot_*() pattern helpers work only inside the pattern argument of the tarpolyglot constructors (tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl(), and their _raw() forms), which rewrite them to the plain targets pattern before building the target. Used directly in a plain targets::tar_target() or targets::tar_target_raw() they raise an error such as invalid dynamic branching pattern ... Illegal symbols found: tarpolyglot_map, because targets validates a pattern against its own fixed set of pattern functions and does not know these helpers. This cannot be fixed from tarpolyglot: targets looks its pattern functions up in a locked internal environment, so teaching it a new one would require modifying the targets package itself. In a plain targets target (which has no foreign code to compile, so nothing to gain) use the native map() / cross() / slice() / head() / tail() / sample() instead.
The other pattern helpers: tarpolyglot_map(), tarpolyglot_cross(), tarpolyglot_head(), tarpolyglot_tail(), tarpolyglot_sample(). The constructors that accept them: tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl()
# square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # post.R: # square(x) tarpolyglot::tar_target_rs( name = rs_some, script = "square.rs", inputs = c(x = "vals"), post_script = "post.R", pattern = tarpolyglot_slice(vals, index = c(1, 3)) )# square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # post.R: # square(x) tarpolyglot::tar_target_rs( name = rs_some, script = "square.rs", inputs = c(x = "vals"), post_script = "post.R", pattern = tarpolyglot_slice(vals, index = c(1, 3)) )
A drop-in replacement for the targets targets::tar_target() pattern helper tail(), for use unquoted in the pattern argument of a tarpolyglot constructor. Like tarpolyglot_map(), on tar_target_rs() it compiles the extendr crate once in a companion <name>_rust_lib target and reuses it across the kept branches; on tar_target_py() / tar_target_jl() it is exactly tail(). See tarpolyglot_map() for the full explanation and the compile-once mechanics.
tarpolyglot_tail(..., n)tarpolyglot_tail(..., n)
... |
Upstream target(s) to branch over, with the same meaning as in the targets |
n |
Number of branches to keep from the end, as in the targets |
This function is a marker consumed by the tarpolyglot constructors and is not meant to be evaluated on its own; calling it directly raises an error.
The tarpolyglot_*() pattern helpers work only inside the pattern argument of the tarpolyglot constructors (tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl(), and their _raw() forms), which rewrite them to the plain targets pattern before building the target. Used directly in a plain targets::tar_target() or targets::tar_target_raw() they raise an error such as invalid dynamic branching pattern ... Illegal symbols found: tarpolyglot_map, because targets validates a pattern against its own fixed set of pattern functions and does not know these helpers. This cannot be fixed from tarpolyglot: targets looks its pattern functions up in a locked internal environment, so teaching it a new one would require modifying the targets package itself. In a plain targets target (which has no foreign code to compile, so nothing to gain) use the native map() / cross() / slice() / head() / tail() / sample() instead.
The other pattern helpers: tarpolyglot_map(), tarpolyglot_cross(), tarpolyglot_slice(), tarpolyglot_head(), tarpolyglot_sample(). The constructors that accept them: tar_target_rs(), tar_target_cpp(), tar_target_py(), tar_target_jl()
# square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # post.R: # square(x) tarpolyglot::tar_target_rs( name = rs_last, script = "square.rs", inputs = c(x = "vals"), post_script = "post.R", pattern = tarpolyglot_tail(vals, n = 2) )# square.rs: # #[extendr] # fn square(x: f64) -> f64 { x * x } # post.R: # square(x) tarpolyglot::tar_target_rs( name = rs_last, script = "square.rs", inputs = c(x = "vals"), post_script = "post.R", pattern = tarpolyglot_tail(vals, n = 2) )
Runs a battery of checks for whichever toolchains you ask for and reports the result with cli as it goes: interpreter/compiler discovery, environment-manager availability, and, most importantly, whether each toolchain is actually reachable from a fresh worker process – the same kind of process crew spawns to run a tar_target_py()/tar_target_jl()/tar_target_rs() step. This is meant to preempt the common "it doesn't run on my machine" class of issue before you find out the hard way, mid-pipeline.
toolchain_check( toolchains = c("py", "jl", "rs", "cpp"), deep = TRUE, quiet = FALSE )toolchain_check( toolchains = c("py", "jl", "rs", "cpp"), deep = TRUE, quiet = FALSE )
toolchains |
Character vector, which toolchains to check: any subset of |
deep |
Logical. When |
quiet |
Logical, default |
Environment managers checked per language: for Python, uv, poetry, and conda (three separate, competing tools, plus the stdlib venv module on the resolved interpreter). For Julia, juliaup (which manages versions, checked via presence + the list of installed versions) and, separately, Julia's own Pkg project-environment mechanism (which manages packages, activated with Pkg.activate() – the actual mechanism behind julia_project/julia_packages): a fresh worker actually activates a throwaway project to prove it works, not just that Julia is present. Rust has no separate environment concept (see vignette("rust")); rustup/cargo/(on Windows) the GNU toolchain and Rtools are checked instead.
Every check that would bind an interpreter (Python, Julia) or compile code (Rust, C++) runs inside a disposable callr::r() subprocess, never in your current R session: this means toolchain_check() cannot leave reticulate or JuliaCall bound afterwards, and it is answering the real question ("would a crew worker be able to do this right now"), not just "is something already loaded in this session". Plain presence checks (Sys.which() for uv, poetry, rustup, and so on, or requireNamespace() for Rcpp) run directly, since they have no side effects to isolate.
When more than one version is found, each language also reports every installed version it can enumerate, with its path and which one is the default (the one a step would actually use if you set nothing): Python via uv python list --only-installed (matched against the resolved interpreter primarily by exact version, since reticulate's default is often an ephemeral uv-provisioned interpreter that lives under uv's cache rather than its "installed" registry, so the two rarely share a literal path even when they are, in fact, the same build); Julia via the juliaup depot; Rust via rustup toolchain list -v (which marks its own default inline, no cross-referencing needed). With only one version found, this is a single summary line instead. C++ has no separate version-manager concept to enumerate this way (see tar_target_cpp()): it compiles via R's own configured toolchain, so its checks are presence (Rcpp; the OS-appropriate compiler, Rtools on Windows or the actual R CMD config CXX compiler command on macOS/Linux, queried rather than guessed so it is correct under gcc or clang alike) plus, with deep = TRUE, a compile-reachability check. Extension packages such as RcppArmadillo/RcppEigen/RcppParallel are not checked here since tarpolyglot itself does not depend on any of them; they are entirely the caller's own choice via depends (see tar_target_cpp()).
Invisibly, a data.frame with one row per check and columns toolchain ("py"/"jl"/"rs"/"cpp"), check (a short label), status ("ok", "warn", or "fail"), and detail (a human-readable description, e.g. the resolved path and version, or an error message).
tar_target_py(), tar_target_jl(), tar_target_rs(), tar_target_cpp()
# Every check runs in a fresh callr subprocess, and with deep = TRUE it also # compiles a trivial function, so this is gated on TARPOLYGLOT_EXAMPLES=true # rather than run on machines with no toolchain installed. if (identical(Sys.getenv("TARPOLYGLOT_EXAMPLES"), "true")) { toolchain_check("py") # Python only toolchain_check(c("jl", "rs")) # Julia and Rust toolchain_check("rs", deep = FALSE) # skip the Rust compile test res <- toolchain_check(quiet = TRUE) # no console output, just the data.frame res[res$status != "ok", ] # anything that needs attention }# Every check runs in a fresh callr subprocess, and with deep = TRUE it also # compiles a trivial function, so this is gated on TARPOLYGLOT_EXAMPLES=true # rather than run on machines with no toolchain installed. if (identical(Sys.getenv("TARPOLYGLOT_EXAMPLES"), "true")) { toolchain_check("py") # Python only toolchain_check(c("jl", "rs")) # Julia and Rust toolchain_check("rs", deep = FALSE) # skip the Rust compile test res <- toolchain_check(quiet = TRUE) # no console output, just the data.frame res[res$status != "ok", ] # anything that needs attention }