tidyverse / purrr

A functional programming toolkit for R
https://purrr.tidyverse.org/
Other
1.28k stars 272 forks source link

incorrect concept of ellipsis in imap #1032

Closed avraam-inside closed 1 year ago

avraam-inside commented 1 year ago

Sometimes I need to pass an ellipsis to the map-family functions. But there are problems.

Let's look at the problem with an example (JUST AN EXAMPLE):

testFunc <- function(.object, ...) {
    purrr::imap(.object, ~{paste(c(.x, .y, 23), ...)}, ...)
}
testFunc(c('sd', 'cxd', 'wtf'), collapse = '+')

What i get:

[[1]]
[1] "sd sd 1+1 sd 1+23 sd 1"

[[2]]
[1] "cxd cxd 2+2 cxd 2+23 cxd 2"

[[3]]
[1] "wtf wtf 3+3 wtf 3+23 wtf 3"

What i expect:

[[1]]
[1] "sd+1+23"

[[2]]
[1] "cxd+2+23"

[[3]]
[1] "wtf+3+23"

The reason is that the implementation of ellipsis in map does not allow me to do this.

testFunc <- function(.object, ...) {
    purrr::imap(.object, ~{browser(); paste(c(.x, .y, 23), ...)}, ...)
}
testFunc(c('sd', 'cxd', 'wtf'), collapse = '+')

Called from: .f(.x[[i]], .y[[i]], ...)
Browse[1]> list(...)
[[1]]
[1] "sd"

[[2]]
[1] 1

$collapse
[1] "+"

As you can see, the ellipsis in the map function contains, in addition to the arguments I passed, also .x and .y.

Question: why? 1) It interferes with my idea 2) There is already one in the environment .x .y, why are their duplicates in ...?

I have a request - please remove from ... in map, the first 2 arguments are not needed, their presence is impractical.

P.S.: Workarounds of this jamb through do.call or something that requires passing a function not directly in the formula, but through "function" or something like that are categorically not suitable!

Acceptable crutch - if they explain to me how to remove from ... the first 2 arguments. But in general, this is a bad decision.

The best solution is to remove the first 2 garbage arguments from ... on the function side.

hadley commented 1 year ago

Use a real function, not the purrr lambda syntax. This is one of the reasons we no longer recommend that syntax.