R无标准评价:得到承诺的价值,同时离开它不计算[或:保持外部指针有效...](R non-stand

2019-10-28 19:14发布

这是一个后续并行化功能,将外部指针(XPTR)

我不会在这里重现.cpp的代码,以使事情更短。 问题是要,一旦一个函数的参数进行评价,则在该函数的环境中定义,并且在外部指针的情况下,是在一个叉簇不再可用。

因此,尽管该功能的工作:

require(parallel)
test1 <- function(a) {
  cl <- makeForkCluster(nnodes=2)
  r <- parLapply(cl, 1:5, function(i) g(a,i) )
  stopCluster(cl)
  unlist(r)
}

此功能没有:

test2 <- function(a) {
  cl <- makeForkCluster(nnodes=2)
  p <- g(a, 0)
  r <- parLapply(cl, 1:5, function(i) g(a,i) )
  stopCluster(cl)
  unlist(r)
}

正如拉尔夫Stubner指出,这是来自一个事实,即呼叫g(a, 0)被迫承诺的评价a 。 他建议下面的解决(有两个调试输出这里了解它是如何工作的):

test3 <- function(a) {
  cl <- makeForkCluster(nnodes = 2)
    print(pryr::promise_info(a))
  b <- eval(substitute(a))
  p <- g(b, 0)
    print(pryr::promise_info(a))
  r <- parLapply(cl, 1:5, function(i) g(a,i) )
  stopCluster(cl)
  unlist(r)
}

这允许接入到任何在a ,但a仍然是一个未计算的承诺。 但是,当这不起作用test3从另一个函数调用!

test4 <- function(b) test1(b)
test5 <- function(b) test3(b)

虽然test4效果很好(递归承诺评价似乎给了一个有效的指针),变通办法test3不再工作从调用时test5

调试打印显示,尽管eval(substitute(a))欺骗,承诺进行评估。 我的理解是,这个招数迫使承诺的评估btest5在其环境中,从而a过评估。

难道还有其他的解决方法吗? (我试过玩pryr::parent_promise从例子,但即使是代码手册页给出了奇怪的结果)。

我有这种类型的其他复杂问题。 一般的方式来获得承诺的内容,而评估它,或者外部指针传递给其他的功能,具有parLapply在最后的呼叫,没有在这个问题上一直磕磕绊绊,会更受欢迎。

文章来源: R non-standard evaluation : get promise value while leaving it unevaluated [or: keep external pointer valid…]