Skip to content

WISH: Support passing name-value pairs via '.args' of mirai() #54

Closed
@HenrikBengtsson

Description

@HenrikBengtsson

Picking up on the side-discussion on argument .args that started in #49 (comment).

As it stands now (mirai 0.8.2.9036), the .args argument of mirai() takes a vector of symbols as input. The following are all working examples:

m <- mirai::mirai(2 * a + b, .args = list(a, b))
m$data
## [1] 10
m <- mirai::mirai(2 * a + b, .args = c(a, b))
m$data
## [1] 10
m <- mirai::mirai(2 * a + b, .args = data.frame(a, b))
m$data
## [1] 10

Issues

Too broad acceptance

?mirai::mirai says that .args takes an "(optional) list of objects". The above .args = c(a, b) example does not use a list. One can also debate whether .args = data.frame(a, b) should work (although technically it's also a list).

No validation of '.args'

There is no up-front validation of what is passed to .args. Instead, mis-specification of .args results in run-time errors from worker failing to evaluate the expression. For example,

m <- mirai::mirai(2 * a + b, .args = c("a", "b"))
m$data
## 'miraiError' chr Error in 2 * a: non-numeric argument to binary operator
m <- mirai::mirai(2 * a + b, .args = alist(a, b))
m$data
## 'miraiError' chr Error in 2 * a: non-numeric argument to binary operator
m <- mirai::mirai(2 * a + b, .args = 42)
m$data
'miraiError' chr Error in eval(expr = envir[[".expr"]], envir = envir, enclos = NULL): object 'a' not found

No support for name-value pairs

I think there will be a lot of users that will expect being able to do:

m <- mirai::mirai(2 * a + b, .args = list(a = 3, b = 4))
m$data
'miraiError' chr Error in eval(expr = envir[[".expr"]], envir = envir, enclos = NULL): object 'a' not found

This will allow users to write more clear code. Currently, anyone who wishes to pass a named list of values has to resort to do.call(), which counter to the "neat API" that mirai tries to support. For example, as it stands now, we have to write code like:

expr <- quote(2 * a + b)
globals <- list(a = 3, b = 4)
m <- do.call(mirai, c(list(expr), globals))

instead of a much cleaner and less obscure:

expr <- quote(2 * a + b)
globals <- list(a = 3, b = 4)
m <- mirai(expr, .args = globals)

Suggestion

  1. Redesign current behavior to support only the .args = c(a, b) form.

  2. Add support for specifying name-value elements, i.e. .args = list(a = 3, b = 4).

I think those will be the most common use cases. Using c() for one and list() for the other could help distinguish the two. Of course, both forms could be handled using list() too.

FWIW, the fact that c(a, b) uses symbols has the advantage that static-code inspection (e.g. codetools validation by R CMD check) can pick up typos. In contrast, .args = c("a", "btypo") won't be detected until run-time.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions