【问题标题】:Create a promise/lazily evaluated expression in R在 R 中创建一个承诺/延迟评估的表达式
【发布时间】:2015-09-29 14:07:20
【问题描述】:

我想以编程方式在 R 中创建一个承诺。我知道该语言支持它。但由于某种原因,似乎没有办法做到这一点。

提供更多细节:我希望对列表的组件进行惰性评估。例如

x <- list(node=i, children=promise(some_expensive_function(i))

我只想访问列表的第二个组件以获取列表的极少数值。用惰性表达式预先填充列表会产生非常清晰、紧凑和可读的代码。该算法的背景是树搜索。本质上,我试图在这里模拟协程行为。现在我为此使用闭包,但代码缺乏优雅。

是否有第三方包暴露了 R 中隐藏的 Promise 构造机制?或者这种机制是否明确地绑定到环境绑定而不是表达式?

附:是的,我知道延迟分配。它没有做我想要的。是的,我可以处理中间环境,但它也很混乱。

【问题讨论】:

  • 我建议您使用“便宜”的功能编写更多代码。

标签: r promise lazy-evaluation coroutine


【解决方案1】:

任何具有一流函数(包括 R)的编程语言都可以通过 thunk (Wikipedia entry on this) 轻松实现惰性求值。

基本思想是函数在被调用之前不会被评估,因此只需将列表中的元素包装在匿名函数中,这些函数在调用时返回它们的值。

delayed <- list(function() 1, function() 2, function () 3)
lapply(delayed, function(x) x())

这些只是包含在其中的数字,但您可以轻松地将 some_expensive_function(i) 放入其中以提供参数但延迟评估。


编辑:刚刚注意到使用闭包的事情,所以我假设您目前正在使用类似的方法。你能详细说明它的“不优雅”吗?这都是旁观者的看法,但是如果您只是在寻找惰性评估,那么 thunking 似乎相当简单,并且样板文件要少得多。

【讨论】:

  • 这正是我现在正在使用的。我认为这是不优雅的,因为需要记住这些是函数,并明确地评估它们(这对于需要使用我的代码的其他用户来说尤其成问题)。如果表达式会被隐式延迟评估,那就太好了。当然,在这一点上,我对这个解决方案的不喜欢几乎是挑剔的。我只是想找到最实用和可维护的解决方案。
【解决方案2】:

目前,您的用例太模糊,我无法理解。我想知道quoteexpressioncall 之一是否是您要的:

x <- list(node=i, children=quote(mean(i))  )
x
#----------
$node
[1] 768

$children
mean(i)
#------------
x <- list(node=i, children=call('mean',i))
x
#-------------
$node
[1] 768

$children
mean(768L)
#-----------
x <- list(node=i, children=expression(mean(i)) )
x
#------------
$node
[1] 768

$children
expression(mean(i))

最后一个测试明显评价在globalenv()

eval( x$children)
#[1] 768

【讨论】:

  • 用例相当简单。我有一个生成搜索树的函数,还有一堆遍历这棵树的其他函数。搜索树可能非常大,但只需要遍历很少的分支。通过延迟评估子树,我可以将性能提高 200 倍或更多,同时保持代码简洁。另一个解决方案是合并树生成和树遍历代码,但出于 API 设计原因,我不想这样做。您的提议与詹姆斯在上述答案中提供的基本相同。它仍然需要明确的评估。
【解决方案3】:

我最终为此使用了环境和延迟分配。

        node <- new.env()
        node$name <- X[1, 1]
        r$level <- names(X)[1]
        delayedAssign('subtaxa', split_taxons_lazy(X[-1]), assign.env=node)

        node

这很适合我的情况,虽然我更喜欢它使用列表,但在 R 中似乎不可能。感谢 cmets!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 2017-02-15
    • 1970-01-01
    相关资源
    最近更新 更多