球拍:在某些范围内进行懒惰评估

时间:2017-02-02 21:44:38

标签: racket lazy-evaluation

Racket为延迟评估提供language extension,只需在某个文件的开头添加#lang lazy标头即可更改整个文件中的评估策略。

但是,这种标准方法只允许课程级别的粒度;需要一种更精细的方法来将惰性评估限制在某个定义的范围内。

Racket是否提供了一些标准方法来将懒惰评估策略限制在某个范围内?我正在寻找以下内容:

(eval-lazy (+ 2 2)) ;; only available by explicit or implicit call-by-need

1 个答案:

答案 0 :(得分:1)

#lang lazy是一种与#lang racket完全不同的语言。是的,您可以混合和匹配某些部分,但在#lang lazy模块中处理来自#lang racket的惰性值会变得混乱。

每个方案,也就是球拍,都有delayforce

(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)))))

thunklambda一样,只是调用结果会强制它。

<强>流

Racket提供了一个stream library,它可以用来完成所有算法的90%,你可以通过这种方式抽象每个步骤,因为它是一个自己的过程,你可以将它们组合在一起而不会受到惩罚。名单。流只是在SICP

中普及的cons中的延迟值