Convert from procedure form to let form

佐手、 提交于 2019-12-02 05:15:04

You can use a let* instead. It allows you to use previously defined bindings in other bindings. For example:

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

Using a regular let this would not work because each binding is oblivious of the other bindings. This is because of the way the let is implemented. Semantically speaking the let above could be translated to something like this:

(let ((x 1)
      (y 2))
  (+ x y))

;; Is equivalent to:

((lambda (x y) (+ x y)) 1 2)

While a let* would be translated to this:

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

;; Is equivalent to:

((lambda (x) ((lambda (y) (+ x y)) 2)) 1)

I suggest you read through this page to understand the difference between let, let* and letrec.

Using let* in your solution yields the following code:

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

However, if you are not allowed to use let* you will have to nest your let statements. This will yield quite ugly, but functional code:

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

The no expression in body error indicates that you have defined a let expression with no expressions in the body. An example of such a let expression could be:

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

Where I typed the dots has to be at least one expression which will be the result of the evaluation of the entire let expression. If there is no expression there the let can not be evaluated to any value, because there is nothing to evaluate. You can also get this error when defining a lambda that has no body, or a function that has no body.

> (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)
> 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!