我想以编程方式在R中创建一个承诺。我知道语言支持它。但由于某种原因,似乎没有办法做到这一点。
提供更多细节:我希望懒惰地评估列表的组件。 E.g。
x <- list(node=i, children=promise(some_expensive_function(i))
我只想访问列表的第二个组件,只列出很少的值。使用惰性表达式预填充列表会产生非常清晰,紧凑和可读的代码。该算法的背景是树搜索。基本上,我试图在这里模仿协程行为。现在我正在使用闭包,但代码缺乏优雅。
是否有第三方软件包暴露了R中隐藏的承诺构建机制?或者这种机制是否明确地与环境绑定相关联而不是表达式?
P.S。是的,我知道延迟分配。它没有做我想要的。是的,我可以玩中间环境,但它也很混乱。
答案 0 :(得分:1)
任何具有一流功能(包括R)的编程语言都可以通过thunks(Wikipedia entry on this)轻松实现延迟评估。
基本思想是函数在被调用之前不会被计算,所以只需将列表元素包装在匿名函数中,这些函数在调用时返回它们的值。
delayed <- list(function() 1, function() 2, function () 3)
lapply(delayed, function(x) x())
这些只是包含在那里的数字,但您可以轻松地将some_expensive_function(i)
放在那里,而不是提供参数,但延迟评估。
编辑:刚才注意到使用闭包的事情,所以我假设你现在正在使用类似的方法。你能详细说明它的“不雅”吗?这是所有人的眼睛,但如果你只是在寻找懒惰的评估,那么thunking似乎相当简单,并且更少的样板。
答案 1 :(得分:0)
目前,您的用例过于模糊,无法理解。我想知道quote
,expression
或call
中的一个是否是您所要求的:
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
答案 2 :(得分:0)
我最终使用环境和delayedAssign这个。
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中似乎不可能。感谢您的评论!