have this procedure form code that I have written in scheme and I need to change it into let form. Here is procedure form 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)))
(main)
Here is what I have implemented so far for my let form code:
(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)
The current error I am getting with my let form code is:
r5rs: body: no expression in body in: (r5rs:body)
Thanks, in advance, for any help with this issue :)
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)
>