从程序表格转换为表格

时间:2015-04-11 09:40:12

标签: scheme racket

有我在程序中编写的程序表单代码,我需要将其更改为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 form form代码实现的内容:

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

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

1 个答案:

答案 0 :(得分:2)

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

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

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