关于懒惰[RAKU] [英] About Laziness [ RAKU ]
问题描述
Raku文档中指出,正在对聚集结构进行惰性评估.在以下示例中,我很难得出关于结构的惰性的结论:
说迭代到无穷大是:",(1 ... Inf).说收集者是:",收集{取0;我的($ last,$ this)= 0,1;环形 {拿$ this;($ last,$ this)= $ this,$ last + $ this;}}.什么;说 ' - - - - - - - - - - - - - - - - - - ';我的@ f1 =懒人聚集{取0;我的($ last,$ this)= 0,1;环形 {拿$ this;($ last,$ this)= $ this,$ last + $ this;}}说'@ f1:',@ f1.说'@ f1 is lazy:',@ f1.is-lazy;说 ' - - - - - - - - - - - - - - - - - - ';我的@ f2 = 1 ... Inf;说'@ f2:',@ f2.说'@ f2 is lazy:',@ f2.is-lazy;
在第一种情况下(将Seq分配给@ f1),如果我们取消了惰性"定义,则生成的Sequence(使用collect-take)将永远运行(不惰性).
在第二种情况下(将Seq分配给@ f2)@ f2变得很懒.
为什么我们在行为上有差异?尽管我们尝试做同样的事情:以惰性方式将Seq分配给数组
有人可以澄清这个问题吗?
Raku文档中指出,正在偷懒评估收集结构.
可以可以.但不一定.他们很高兴以任何一种方式工作.
在按键扭曲中,如果聚集
是请求(如果它是惰性的),它将返回 False
.这就是导致您看到的行为的原因.
采取#1: gather
表现懒惰
的一种方式 gather
在需要时评估其顺序中的下一个元素.这是懒惰评估的经典定义,如Wikipedia所述:
惰性评估...延迟对表达式的评估,直到需要其值为止
采取#2: gather
表现懒惰
的第二种方式一些使用值序列的构造总是懒惰地使用它们.如果他们使用的序列是 In the second case (assignement of a Seq to @f2) @f2 becomes lazy. Why do we have a differentiation in behaviour? although we try to do the same thing: Assign a Seq to an array in a lazy way Can someone clarify the matter ??? In Raku documentation it is stated that gather-take constructs are being lazy evaluated. They can be. But not necessarily. They're perfectly happy to work either way. In a key twist, if a lazy evaluation ... delays the evaluation of an expression until its value is needed
Some constructs that consume sequences of values always consume them lazily. If the sequence they're consuming is a Some constructs that consume sequences of values always consume them eagerly. If a sequence they're consuming is a Some constructs that consume sequences of values demand them either lazily or eagerly, based on the sequence's answer to an And here comes a critical twist: when gather
,则他们会懒惰地要求其值.在这种情况下, gather
会强制执行,评估其顺序,直到达到 take
,然后
gather
is asked if it's lazy, it returns False
. This is what results in the behaviour you see.Take #1: One way
gather
behaves lazilygather
evaluates the next element in its sequence when it's needed. This is the classic definition of lazy evaluation, as described by Wikipedia:
Take #2: A second way
gather
behaves lazilygather
, they demand its values lazily. In which case the gather
obliges, evaluating its sequence until it reaches a take
, and then yielding until the next value is demanded.Take #3: One way
gather
behaves eagerlygather
, they demand its values eagerly. In which case the gather
obliges, and any laziness in it is moot.Take #4: A second way
gather
behaves eagerly.is-lazy
call on it; if it returns True
, then its values are demanded lazily, otherwise they're demanded eagerly..is-lazy
is called on a gather
construct, it returns False
.Take #5: What's happening in your examples
say .is-lazy
for (gather { take 42 }), # False
(gather { loop { take 42 } }); # False
In your @f1 = gather ...
case, @f1
is being assigned a sequence that says it's not lazy. This is so even though it contains an infinite loop. @
sigil'd variables take that as a cue to eagerly assign the sequence -- and the code hangs.
The prefix lazy
creates a new Seq
that lazily draws from the expression on its right. It also returns True
if .is-lazy
is called on it:
say .is-lazy
for (lazy gather { take 42 }), # True
(lazy gather { loop { take 42 } }); # True
If an @
sigil'd variable is assigned a value that returns True
for a call to .is-lazy
, the assignment, and the variable, are lazy. So the code @f1 = lazy gather ...
works fine.
Finally, the sequence (1...Inf)
knows it's lazy, and tells the world it is, without needing a prefix lazy
:
say .is-lazy with (1 ... Inf) # True
So assigning that also works fine, with or without lazy
.
In summary, an @
sigil'd variable gains elements lazily if a Seq
assigned to it says it's lazy, and eagerly otherwise.
You didn't ask about this, but another scenario is assigning or binding a Seq
to a $
sigil'd variable, or a sigil free identifier.
As with a @
sigil'd variable, calling .is-lazy
on the $
sigil'd variable or sigil free identifier will return True
or False
in accord with the assigned/bound Seq
.
But then, regardless of whether that .is-lazy
returns True
or False
, the Seq
will still be iterated lazily.
这篇关于关于懒惰[RAKU]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!