You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: vignettes/future-4-issues.md.rsp
+97Lines changed: 97 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -249,6 +249,103 @@ or equivalently
249
249
Note, do _not_ use `library()` or `loadNamespace()` to resolve these problems. It is always better to use the above `packages` approach.
250
250
251
251
252
+
## '...' used in an incorrect context
253
+
254
+
In R, we can use the `...` construct is used to refer to zero or more
255
+
arguments. For example, we can use as in:
256
+
257
+
```r
258
+
my_mean <- function(x, ...) mean(x, ...)
259
+
260
+
y <- my_mean(1:10, trim = 0.1, na.rm = FALSE)
261
+
```
262
+
263
+
This makes sure that the `trim` and the `na.rm` arguments are pass
264
+
down to the `mean()` function.
265
+
266
+
We can also use it to pass arguments in map-reduce calls to anonymous
267
+
functions as in:
268
+
269
+
```r
270
+
X <- rnorm(10)
271
+
y <- lapply(X, FUN = function(x, ...) {
272
+
round(x, ...)
273
+
}, digits = 3)
274
+
```
275
+
276
+
Note how `digits = 3` is pass to the anonymous function via its `...`
277
+
argument, which is then passed on to `round()`, effectively calling
278
+
`round(X[[1]], digits = 3)`, `round(X[[2]], digits = 3)`, and so on.
279
+
280
+
If we take this one step further, we might see things like:
281
+
282
+
```r
283
+
my_fcn <- function(X, ...) { ## outer '...'
284
+
y <- lapply(X, FUN = function(x, ...) { ## inner '...'
285
+
round(x, ...) ## inner '...'
286
+
}, ...) ## outer '...'
287
+
y
288
+
}
289
+
290
+
X <- rnorm(10)
291
+
y <- my_fcn(X, digits = 3)
292
+
```
293
+
294
+
In this case, we have two levels of `...` arguments; one for
295
+
`my_fcn()` and one for the anonymous function. Note how the `...`
296
+
arguments for `my_fcn()` are passed down to the anonymous function by
297
+
specifying `...` as an final argument to `lapply()`.
298
+
299
+
The above is the ideal and proper way to pass down `...`. However, it
300
+
is not uncommon to see that the `...` is used as a global variable in
301
+
anonymous functions. For example, you might find:
302
+
303
+
```r
304
+
my_fcn <- function(X, ...) { ## outer '...'
305
+
y <- lapply(X, FUN = function(x) {
306
+
round(x, ...) ## outer '...' as global variables
307
+
})
308
+
y
309
+
}
310
+
```
311
+
312
+
This will also work, because `...` becomes a global variable in the
313
+
environment of the anonymous function. Although we know that relying
314
+
on global variables is a bad idea, this one often slips through.
315
+
316
+
If we attempt to do the same with the future framework, or other
317
+
parallel frameworks, it might not work. For example, using:
318
+
319
+
```r
320
+
my_fcn <- function(X, ...) {
321
+
y <- future_lapply(X, FUN = function(x) {
322
+
round(x, ...)
323
+
})
324
+
y
325
+
}
326
+
```
327
+
328
+
might result in an error on:
329
+
330
+
```
331
+
Error: '...' used in an incorrect context
332
+
```
333
+
334
+
Even you do not get this error, it is always a good idea to make sure
335
+
`...` is passed as an argument all the way down to where it is used,
336
+
e.g.
337
+
338
+
```r
339
+
my_fcn <- function(X, ...) {
340
+
y <- future.apply::future_lapply(X, FUN = function(x, ...) {
341
+
round(x, ...)
342
+
}, ...)
343
+
y
344
+
}
345
+
```
346
+
347
+
348
+
252
349
## Non-exportable objects
253
350
254
351
Certain types of objects are tied to a given R session and cannot be passed along to another R process (a "worker"). An example of a non-exportable object is is XML objects of the **[xml2]** package. If we attempt to use those in parallel processing, we may get a error when the future is evaluated (or just invalid results depending on how they are used), e.g.
0 commit comments