The following is a function that sums 1/2^n until it reaches 0 . Can someone tell me whether or not I need an else statement, and how to arrange my parenthesis so there are no compile errors?
(define (zeno n)
(if (= n 0)
(+ 0)
(else
((+ (/ 1 (expt 2 n )))
((zeno(- n 1)))))))
I have my hat, my tea, and nothing to do for a while at work. You know what time it is.
[dons code-review hat]
Firstly, if you had properly indented your code, it would read
(define (zeno n)
(if (= n 0)
(+ 0)
(else
((+ (/ 1 (expt 2 n)))
((zeno (- n 1)))))))
if
in Scheme is not like the if
/ then
/ else
construct of C-like languages. It's actually the ternary operator . In other words, else
makes no sense in this context.
(define (zeno n)
(if (= n 0)
(+ 0)
((+ (/ 1 (expt 2 n)))
((zeno (- n 1)))))))
You don't need to use +
to return a number; numbers are self-evaluating.
(define (zeno n)
(if (= n 0)
0
((+ (/ 1 (expt 2 n)))
((zeno (- n 1)))))))
When you have an expression like (foo bar baz)
, it usually means
"Call the function
foo
with argumentsbar
andbaz
"
You can't just add extra parentheses as you please; those change the meaning of the expression. For example, ((foo) (bar baz))
means
"Call the function
foo
with no arguments, and call its result with the result of callingbar
with the argumentbaz
"
In other words,
...
((+ (/ 1 (expt 2 n)))
((zeno (- n 1))))))
what you're saying, and almost certainly don't mean, here is
"Call the function
(+ (/ 1 (expt 2 n)))
with the result of calling the result of callingzeno
with the argument(- n 1)
with no arguments."
What you seem to mean is
"Add
1
divided by2^n
to the result of callingzeno
with one less thann
"
Which means that what you should say is
(define (zeno n)
(if (= n 0)
0
(+ (/ 1 (expt 2 n))
(zeno (- n 1)))))
You have a couple of syntax errors (erroneous parenthesis, mostly), and the if
form doesn't use else
- don't get me wrong, it does have an "else" part, it's just that you must not explicitly write else
for it to work. I believe this is what you were aiming for:
(define (zeno n)
(if (= n 0)
0
(+ (/ 1 (expt 2 n))
(zeno (- n 1)))))
For a completely different approach, this uses an explicit do
loop to do the summing. It avoids using expt
(by design).
(define (zeno n)
(do ((n n (- n 1))
(sum 0 (+ sum frac))
(frac 1/2 (/ frac 2)))
((zero? n) sum)))
It may or may not be more readable when written into its equivalent named let
form:
(define (zeno n)
(let loop ((n n)
(sum 0)
(frac 1/2))
(if (zero? n)
sum
(loop (- n 1) (+ sum frac) (/ frac 2)))))
For an even more completely different approach, you can use SRFI 41 streams:
(define zeno
(let ((frac-stream (stream-iterate (cut / <> 2) 1/2)))
(lambda (n)
(stream-fold + 0 (stream-take n frac-stream)))))
(The above snippet also requires SRFI 26 to be loaded, in addition to SRFI 41.)
An even even more completely different approach: just use the closed-form solution! (Thanks, WorBlux.)
(define (zeno n)
(- 1 (/ (expt 2 n))))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.