从过程形式转换为让形式

Convert from procedure form to let form

有我在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)

提前感谢您对此问题的任何帮助:)

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

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

使用常规 let 这将不起作用,因为每个绑定都忽略了其他绑定。这是因为 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)
>