Похоже, что это вариант 2. Попробуйте:
f <- function(x, y) x + y
yy <- 5
fp1 <- partial(f, y = !! yy)
debugonce(f)
fp1(3)
Здесь вы можете увидеть, что в RStudio отладчик откроет исходную функцию f
, для которой аргументы x = 3
и y = 5
пройдены. Однако частичная функция вызывает не реальную функцию f
, а ее копию в кавычках. Если вы измените f
после того, как он был частично выделен, отладчик его больше не найдет.
f <- function(x, y) x + y
yy <- 5
fp1 <- partial(f, y = !! yy)
f <- function(x, y) x + 2 * y
debugonce(f)
fp1(3) # debugger will not open
Можно имитировать c поведение partial
, построив функцию для частичной самоопределения. Однако в этом случае ни f
, ни yy
не захватываются, поэтому их изменение повлияет на вывод вашей частичной функции:
f <- function(x, y) x + y
yy <- 5
# similar to `partial` but captures neither `f` nor `yy`
fp2 <- function(x) f(x, yy)
fp2(3)
#> [1] 8
# so if yy changes, so will the output of fp2
yy <- 10
fp2(3)
#> [1] 13
# and if f changes, so will the output of fp2
f <- function(x, y) x + 2 * y
fp2(3)
#> [1] 23
Создано 13.07.2020 пакет REPEX (v0.3.0)
Чтобы лучше понять, как работает partial
, мы можем построить функцию simple_partial
следующим образом:
library(rlang)
f <- function(x, y) x + y
yy <- 5
simple_partial <- function(.f, ...) {
# capture arguments
args <- enquos(...)
# capture function
fn_expr <- enexpr(.f)
# construct call with function and supplied arguments
# in the ... go all arguments which will be supplied later
call <- call_modify(call2(.f), !!! args, ... = )
# turn call into a quosure (= expr and environment where it should be evaluated)
call <- new_quosure(call, caller_env())
# create child environment of current environment and turn it into a data mask
mask <- new_data_mask(env())
# return this function
function(...) {
# bind the ... from current environment to the data mask
env_bind(mask, ... = env_get(current_env(), "..."))
# evaluate the quoted call in the data mask where all additional values can be found
eval_tidy(call, mask)
}
}
fp3 <- simple_partial(f, y = !! yy)
fp3(1)
#> [1] 6
Создано 13.07.2020 пакетом REPEX. (v0.3.0)