(let ((x 2) (y 3)
(let ((x 7)
(z (+ x y)))
(* z x)))
With the code above, why is the answer 35, not 70? In the second let, x is 7 so z should be 7 + 3 = 10, and then the result should be 7 * 10 = 70. I know got another is let* I am very confusing between this 2. The sample is grabs from google. I already google but just can't get it.
To expand on Leppie's answer: if you had written
(let ((x 2) (y 3))
(let* ((x 7)
(z (+ x y)))
(* z x)))
you would get the answer you expected. The internal let* is exactly equivalent to
(let ((x 7))
(let ((z (+ x y)))
(* z x)))
and in fact might be implemented that way in some Schemes.
In other words, in a let* form each successive binding after the first is in the scope of all the previously created bindings.
x is still bound to the outer let when calling (+ x y).
Related
I'm trying to review my final exam in R5RS, but having trouble with a simple problem. My professor isn't really helpful and I don't know anybody in my class. Can you help me?
The function ratio takes in two parameters f (function) and x (a number). I had to use a let statement. The scheme function is supposed to produced an outcome for:
f(x)+f(x+1)/f(x)
This is what I have so far:
(define (ratio f x)
(let ((f (+ x 1)))
(/ (+ x (+ f 1))
x)))
(ratio (lambda (x) (+ x 2)) 3)
I tried working with this for an hour, but still can't get the right answer.
Hint: let a = f(x) and let b = f(x + 1). What should the output be in terms of a and b?
In your solution, you bind f to the value of x + 1. So your solution is really calculating (x + (x + 2)) / x. You need to apply f to x, ie (f x).
Here is a start:
(define (ratio f x)
(let ((a (f x)) (b (f (+ x 1))))
...))
Math Scheme
f(x) (f x)
x+1 (+ x 1)
f(x+1) (f (+ x 1))
a/b (/ a b)
a/f(x) (/ a (f x))
f(x+1)/f(x) (/ (f (+ x 1)) (f x))
c + f(x+1)/f(x) ?
f(x) + f(x+1)/f(x) ?
The following is in my class notes for Scheme:
(let ((x 2) (y 3))
(let ((x 7) (z (+ x y)))
(* z x)))
The answer yields 35. Can someone explain this to me?
So on the 2nd line z(+x y) the x value seems to be 2 but after that (* z x) the x value is 7? Thanks a lot
(let ((x 2) (y 3))
Here the 1st let is still in charge until all values have been bound.
(let ((x 7) (z (+ x y)))
Here the 2nd let is in charge.
(* z x)))
If you want (x 7) to be used in (z (+ x y)) then try let*
TEST
(let ((x 2) (y 3))
(let ((x 7) (z (+ x y)))
(* z x)))
> 35
(let ((x 2) (y 3))
(let* ((x 7) (z (+ x y)))
(* z x)))
> 70
Hope it helps.
Perhaps the easier way to explain this is by looking at let as syntax sugar for anonymous procedure calls.
(let ((x 2) (y 3))
(let ((x 7) (z (+ x y)))
(* z x)))
Is the same as:
((lambda (x y)
((lambda (x z)
(* z x)) ; first here is x 7
7
(+ x y))) ; this x is from the outer
2
3)
I was wondering if I would be able to use the built in let function from scheme to define two random variables within the function without their values changing throughout the code. For example if I wrote:
(let (x (- (* 2 (random)) 1)))
(let (y (- (* 2 (random)) 1)))
Would the value of x be constant until the function exits? I want to square x and y and take the square root of them, but I need their values to remain the same.
Yes, let binds a value to the given identifier, and its value doesn't change unless you use set! on it.
So you can do this:
(let ((x (- (* 2 (random)) 1))
(y (- (* 2 (random)) 1)))
(sqrt (+ (* x x) (* y y))))
Of course, I find it easier to define a hypot function for what you're doing (corresponding to C's hypot function):
(define (hypot x y)
(sqrt (+ (* x x) (* y y))))
(hypot (- (* 2 (random)) 1)
(- (* 2 (random)) 1))
Now you don't need to use let at all!
In case the connection isn't immediately obvious, the way let works behind the scenes is to create a function (with pretty much the same contents as hypot, in this case), and just calls that function with the values you're binding. So, the two snippets of code above are effectively identical (except that the latter one also adds a top-level binding for hypot).
I am currently trying to learn Scheme to run FDTD simulations and I am having trouble building a Gaussian function in 2 dimensions.
In a forum I found this possibility for 1D:
(define ( (gaussx sigma) x)
(exp (- (/ (vector3-dot x x) (* 2 sigma sigma)))))
which if I understood currying correctly is equivalent to:
(define (gauss sigma)
(lambda(x)
(exp (- (/ (vector3-dot x x) (* 2 sigma sigma))))))
Now I would like the function to be gaussian along both x and y directions but I don't understand why this doesn't work:
(define (gauss sigma)
(lambda(x)
(lambda(y)
(exp (- (/ (+ (vector3-dot y y) (vector3-dot x x)) (* 2 sigma sigma))))
When I call
(gauss 1)
I get the following message:
ERROR: Wrong type (expecting real number): # <procedure> #f (y)
Does someone see what I am doing wrong? I also tried other solutions but I don't seem to get the logics here...
Thanks a lot for your help!
Best regards
Mei
I don't think there's need for a double currying here, try this:
(define (gauss sigma)
(lambda (x y)
(exp (- (/ (+ (vector3-dot y y) (vector3-dot x x)) (* 2 sigma sigma))))))
Call it like this:
(define gauss-1 (gauss 1))
(gauss-1 some-x some-y)
But if you definitely need the double currying, this should work:
(define (gauss sigma)
(lambda (x)
(lambda (y)
(exp (- (/ (+ (vector3-dot y y) (vector3-dot x x)) (* 2 sigma sigma)))))))
Using it like this:
(define gauss-1 (gauss 1))
((gauss-1 some-x) some-y)
I've just started working through this book for fun; I wish it were homework, but I could never afford to attend MIT, and there are tons of people smarter than me anyway. :p
fast-exp is supposed to find b^n, i.e. 4^2 = 16, 3^3 = 27
(define (fast-exp b n)
(define (fast-exp-iter n-prime a)
(cond ((= n-prime 1) a)
((= (remainder n-prime 2) 1) (fast-exp-iter (- n-prime 1) (* a b)))
(else (fast-exp-iter (/ n-prime 2) (* a b b)))))
(fast-exp-iter n 1))
fast-exp 4 2; Expected 16, Actual 2
You forgot to call fast-exp. Instead, you evaluated three separate atoms. To actually evaluate the fast-exp of 4 to the 2, you'd have to write
(fast-exp 4 2)
The solution you have written here is also incorrect. e.g. Check out (fast-exp 2 6). Expected: 64, actual: 32.
Your solution is calculating wrong answers. (See http://ideone.com/quT6A) In fact, how you in principle can write a tail-recursive fast exponentiation passing only two numbers as arguments? I don't think it's even possible, because in the middle of computation you don't know what multiplier to use if you encounter odd exponent.
But I can give an example of working solution that is exactly what is expected by SICP authors (iterative process using "invariant quantity" (a * b^n), where a is initially 1)
(define (pow x y)
(define (powi acc x y)
(cond
((= y 0) acc)
((odd? y) (powi (* acc x) x (- y 1)))
(else (powi acc (* x x) (/ y 2)))))
(powi 1 x y))