Perl 5中的惰性评估技术示例?

时间:2010-12-07 22:34:05

标签: perl haskell lazy-evaluation

我发现Haskell和Perl6最有趣的特性之一是能够推迟计算值,直到实际需要它们为止。

另一方面,Perl5喜欢立即做所有事情,但据我所知,它包含了懒惰评估的所有必要原语。那些是:

  • 在子例程中引用@_会创建一个数组引用,该引用的别名是其参数列表中的标识符,即使其中一些标识符尚未包含值。
  • 从内部保存\@_的子例程中返回重载/绑定对象,然后在需要时取消引用它。 (并且有各种CPAN模块可以抽象出领带/过载细节)

我一直在Perl中尝试各种懒惰的编程技术(我在工作中有一个模块,它在Perl5中实现了相当多的Haskell Prelude(像共同递归:$_ = list 0, 1, zipWith {&sum} $_, tail $_ for my $fibs;来定义Fibonacci顺序已经工作))。但我觉得代码中隐藏着一些微妙的错误,这些错误可能会在函数用于较大的表达式/程序时出现。

所以我想知道是否有任何好的例子(CPAN /博客/书籍),任何人都知道在Perl5中使用Haskell / Perl6就像懒惰一样?特别是,我想阅读使用这种懒惰的任何重要代码。

我也有兴趣知道是否有人遇到任何关于Perl 5中延迟评估实现的问题或棘手的问题。

3 个答案:

答案 0 :(得分:9)

高阶Perl(免费提供online)有一章叫做“Infinite Streams”。也许这是一个很好的起点。

答案 1 :(得分:6)

好吧,Moose通过lazy loading of attributes执行此操作:

  

默认和构建器方法
      属性可以有默认值,Moose提供了两种指定默认值的方法       [描述了“默认”和“构建器”选项...]

     

<强>懒惰
    Moose允许您通过使属性“懒惰”来推迟属性填充:

has 'size' => (
    is      => 'ro',
    lazy    => 1,
    builder => '_build_size',
);
     

当“lazy”为真时,在调用reader方法之前不会生成默认值,而不是在对象构造时生成。有几个原因     你可能会选择这样做。

     

首先,如果此属性的默认值取决于某些其他属性,则该属性必须为“lazy”。在对象构造期间,默认值     不是以可预测的顺序生成的,因此在生成默认值时,您不能指望正在填充的其他属性。

     

其次,在需要之前通常没有理由计算默认值。使属性“延迟”可以将成本推迟到属性之前     需要。如果永远不需要该属性,则可以节省一些CPU时间。

     

我们建议您使用构建器或非平凡的默认“懒惰”来创建任何属性。

答案 2 :(得分:4)

我认为最大的问题是“魔法的冲突”。当你想要做一些你觉得很漂亮的事情时,其他一些模块作者正在尝试他们认为很漂亮的东西,结果是不确定的。谁的魔法赢了?

由于人们总是可以窥探另一个变量的魔力,或者甚至无意中将其贬低,因此魔法并不是防弹的。

如果你能通过详尽的案例测试达到100%的正交性,你可能会更容易......也许。