【问题标题】:Convert from procedure form to let form从过程形式转换为让形式
【发布时间】:2015-06-17 01:17:09
【问题描述】:

有我在scheme中编写的这个程序表单代码,我需要将其更改为let表单。这是程序表单代码:

(define PI 3.14159265)

(define areac (lambda (d)
                (* PI (/ d 2) (/ d 2))))

(define volumec (lambda (d h)
                  (*(areac d)(/ h 3))))

(define TotalVolume (lambda()
                      (+(volumec 1 1) (volumec 2 2) (volumec 3 3) (volumec 4 4) (volumec 5 5))))

(define main (lambda()
               (TotalVolume)))

(main)

这是我迄今为止为我的 let 表单代码实现的内容:

(define volumec
  (lambda(d h)
    (let
        ((PI 3.14159265))
      (let
          ((areac
            (lambda(d)
              (*PI(/ d 2)(/ d 2))
              (*
               (/ h 3)))))))))

(define TotalVolume (lambda()
                      (+(volumec 1 1) (volumec 2 2) (volumec 3 3) (volumec 4 4) (volumec 5 5))))

(define main (lambda()
               (TotalVolume)))

(main)

我的 let 表单代码当前出现的错误是:

r5rs: body: no expression in body in: (r5rs:body)

在此先感谢您提供有关此问题的任何帮助 :)

【问题讨论】:

    标签: scheme racket


    【解决方案1】:

    您可以改用let*。它允许您在其他绑定中使用先前定义的绑定。例如:

    (let* ((x 1)
           (y (+ x 1)))
      y)
    

    使用常规的 let this 是行不通的,因为每个绑定都忽略了其他绑定。这是因为 let 的实现方式。从语义上讲,上面的 let 可以翻译成这样的:

    (let ((x 1)
          (y 2))
      (+ x y))
    
    ;; Is equivalent to:
    
    ((lambda (x y) (+ x y)) 1 2)
    

    虽然let* 会被翻译成这样:

    (let* ((x 1)
          (y 2))
      (+ x y))
    
    ;; Is equivalent to:
    
    ((lambda (x) ((lambda (y) (+ x y)) 2)) 1)
    

    我建议您通读this page 以了解letlet*letrec 之间的区别。

    在您的解决方案中使用 let* 会产生以下代码:

    ; (define PI 3.14159265)
    ; 
    ; (define areac (lambda (d)
    ;                 (* PI (/ d 2) (/ d 2))))
    ; 
    ; (define volumec (lambda (d h)
    ;                   (*(areac d)(/ h 3))))
    ; 
    ; (define TotalVolume (lambda()
    ;                       (+(volumec 1 1) (volumec 2 2) (volumec 3 3) (volumec 4 4) (volumec 5 5))))
    ; 
    ; (define main (lambda()
    ;                (TotalVolume)))
    
    ;; Is equivalent to:
    
    (define main (let* ((PI 3.14159265)
                        (areac (lambda (d)
                                 (* PI (/ d 2) (/ d 2))))
                        (volumec (lambda (d h)
                                   (*(areac d)(/ h 3))))
                        (TotalVolume (lambda()
                                       (+(volumec 1 1) (volumec 2 2) (volumec 3 3) (volumec 4 4) (volumec 5 5)))))
                   (lambda()
                     (TotalVolume))))
    (main)
    

    但是,如果不允许使用 let*,则必须嵌套 let 语句。这将产生非常丑陋但功能强大的代码:

    ;; Is equivalent to:
    
    (define main (let ((PI 3.14159265))
                   (let ((areac (lambda (d)
                                  (* PI (/ d 2) (/ d 2)))))
                     (let ((volumec (lambda (d h)
                                      (*(areac d)(/ h 3)))))
                       (let ((TotalVolume (lambda()
                                            (+(volumec 1 1) (volumec 2 2) (volumec 3 3) (volumec 4 4) (volumec 5 5)))))
                       (lambda()
                         (TotalVolume)))))))
    (main)
    

    no expression in body 错误表示您定义了一个 let 表达式,但正文中没有表达式。这种 let 表达式的一个例子可能是:

    (let ((x =1))
      ...)
    

    我输入的点必须至少是一个表达式,这将是整个 let 表达式的评估结果。如果那里没有表达式,则无法将 let 评估为任何值,因为没有要评估的内容。在定义没有主体的 lambda 或没有主体的函数时,也可能出现此错误。

    > (define (f x))
    r5rs:body: no expression in body in: (r5rs:body)
    > (lambda (x))
    r5rs:body: no expression in body in: (r5rs:body)
    > (let ((x 1)))
    r5rs:body: no expression in body in: (r5rs:body)
    > 
    

    【讨论】:

      猜你喜欢
      • 2015-01-10
      • 2015-12-04
      • 1970-01-01
      • 2015-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多