Racket为延迟评估提供language extension,只需在某个文件的开头添加#lang lazy
标头即可更改整个文件中的评估策略。
但是,这种标准方法只允许课程级别的粒度;需要一种更精细的方法来将惰性评估限制在某个定义的范围内。
Racket是否提供了一些标准方法来将懒惰评估策略限制在某个范围内?我正在寻找以下内容:
(eval-lazy (+ 2 2)) ;; only available by explicit or implicit call-by-need
答案 0 :(得分:1)
#lang lazy
是一种与#lang racket
完全不同的语言。是的,您可以混合和匹配某些部分,但在#lang lazy
模块中处理来自#lang racket
的惰性值会变得混乱。
每个方案,也就是球拍,都有delay
和force
:
(define promise (delay (+ 2 2)))
(force promise) ; ==> 4
然而,这只是语法糖,因为你可以这样做:
(define promise (thunk (+ 2 2)))
(promise) ; ==> 4
当然thunk
只是没有参数的匿名函数的语法糖:
(define promise (lambda () (+ 2 2)))
(promise) ; ==> 4
现在delay
实际上稍微复杂一些,因为如果你调用这些函数,它每次都会运行表达式。为了防止我们记住结果。在这里,我将eval-lazy
实现为宏:
(define ^not-calculated (list #f)) ; unique value
(define-syntax eval-lazy
(syntax-rules ()
((_ expression)
(let ((value ^not-calculated))
(lambda ()
(when (eq? ^not-calculated value)
(set! value expression))
value)))))
与thunk
和lambda
一样,只是调用结果会强制它。
<强>流强>
Racket提供了一个stream library,它可以用来完成所有算法的90%,你可以通过这种方式抽象每个步骤,因为它是一个自己的过程,你可以将它们组合在一起而不会受到惩罚。名单。流只是在SICP
中普及的cons
中的延迟值