Description
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
-
Redesign current behavior to support only the
.args = c(a, b)
form. -
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