Racket PLAI中第76页{with{x3}{&x2B;xx}}的评估

Racket PLAI中第76页{with{x3}{&x2B;xx}}的评估,racket,lazy-evaluation,plai,Racket,Lazy Evaluation,Plai,我正在学习第8章“实施懒惰”,并完成了以下CFAE/L: (define-type CFAE/L [num (n number?)] [add (lhs CFAE/L?)(rhs CFAE/L?)] [id (name symbol?)] [fun (param symbol?)(body CFAE/L?)] [app (fun-expr CFAE/L?)(arg-expr CFAE/L?)]) (define-ty

我正在学习第8章“实施懒惰”,并完成了以下CFAE/L:


    (define-type CFAE/L
      [num (n number?)]
      [add (lhs CFAE/L?)(rhs CFAE/L?)]
      [id (name symbol?)]
      [fun (param symbol?)(body CFAE/L?)]
      [app (fun-expr CFAE/L?)(arg-expr CFAE/L?)])

    (define-type CFAE/L-Value
      [numV (n number?)]
      [closureV (param symbol?)
            (body CFAE/L?)
            (env Env?)]
      [exprV (expr CFAE/L?)
         (env Env?)])

      (define-type Env
        [mtSub]
        [aSub (name symbol?)(value CFAE/L-Value?)(env Env?)])

    (define (num+ x y) ;; need this because we can't just use Scheme + to add FAE-values
      (numV (+ (numV-n x) (numV-n y))))

    (define (parse sexp)
      (cond [(number? sexp) (num sexp)]
        [(symbol? sexp) (id sexp)]
        [(list? sexp)
         (case (first sexp)
           ((+)
            (add (parse (second sexp))
                 (parse (third sexp))))
           ((with)                                 
            (app (fun (first (second sexp))        
                      (parse (third sexp)))        
                 (parse (second (second sexp)))))  
           ((fun)                                  
            (fun (first (second sexp))             
                 (parse (third sexp))))            
           (else
            (app (parse (first sexp))            
                 (parse (second sexp)))))]))
   (define (lookup name env)
      (type-case Env env
        [mtSub() (error 'lookup "no binding for identifier")]
        [aSub (bound-name bound-value rest-ds)
          (if (symbol=? bound-name name)
              bound-value
              (lookup name rest-ds))]))

   (define (interp expr env)
      (type-case CFAE/L expr
        [num (n) (numV n)]
        [add (l r)(num+ (interp l env)(interp r env))]
        [id (v) (lookup v env)]
        [fun (bound-id bound-body)
         (closureV bound-id bound-body env)]
          [app (fun-expr arg-expr)
         (local ([define fun-val (interp fun-expr env)]
                 [define arg-val (exprV arg-expr env)])
           (interp (closureV-body fun-val)
                   (aSub (closureV-param fun-val)
                         arg-val
                         (closureV-env fun-val))))]))
根据这个翻译,我想评估page76的

{with {x 3} {+ x x}}
(1) 键入时:

(interp(解析{with{x3}{+xx}}}{mtSub}) 我得到的错误如下:

numV-n:合同违约,预期:numV?,给定:(exprV(num 3)(mtSub)) 合同来源:numV-n,责任:使用 合同:(->numV?编号?) 位于:/study/lisp/plai/chapter8.scm:10.9

(2) 我想手工写下理解page76描述的步骤,如下所示: “解释器将主体中的每个x计算为表达式闭包(因为这是环境中绑定到x的内容),但加法过程无法处理这些问题:它(以及类似的任何其他算术原语)需要确切知道表达式闭包对应的数字。”,但在完成这些步骤后,我仍然不清楚这个描述。以下是我的步骤:(interp(parse)(带有(x3)(+x))(mtSub))

第1步:(解析)(带(x 3)(+x x)))=>(应用程序(fun'x(add(id'x)(id'x)))(num 3))

步骤2:(cloSureV'x(添加(id'x)(id'x))(mtSub))(作为fun val)

步骤3:(interp(add(id'x)(id'x))(aSub'x(num 3)(mtSub)))

提前谢谢

ad1)

这是预期的行为。您收到的错误消息是:

 numV-n: contract violation, 
   expected: numV?, 
   given: (exprV (num 3) (mtSub)) 
   ...
这个
numV-n
num+
中的一个。这在上一篇文章中得到了解释 第75页第段。诸如
num+
之类的原语应为非闭包 值,但值
(exprV(num 3)(mtSub))
是关闭的数字3 在空旷的环境中

因此,诸如
num+
之类的原语必须强制使用参数。 第76页:

(define (num+ n1 n2)
    (numV (+ (numV-n (strict n1) ) (numV-n (strict n2) ))))
广告2)

1)的解释对2)有帮助吗

增加

为什么不让口译员给你写下步骤呢

快速解决方案:

(define (interp expr env)
      (displayln (list 'expr expr 'env env))
      (type-case CFAE/L expr
要获得更可读的输出,请首先写入转换
将CFAE/L转换为(可读)字符串。

我认为1)的解释对2)没有帮助,但作者应该想表达这一点,不是吗?@abelard20008我建议让解释器为您打印步骤。
(define (num+ n1 n2)
    (numV (+ (numV-n (strict n1) ) (numV-n (strict n2) ))))
(define (interp expr env)
      (displayln (list 'expr expr 'env env))
      (type-case CFAE/L expr