Scheme let bound statements - scheme

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)

Related

How to produce a stream of guesses for the root of f?

I would like to produce a stream of guesses for the root of f with 3 arguments f fx and x with f = sin(x) and x = 3. I tried some code but i don't get it. I would appreciate it if you could provide me some help.
(define (stream f fx x)
(let ((x (3))
((f x) (sin x))
((fx x) (cos x)))
(cons-stream (x (stream f fx (x (- x (/ (f x) (fx x)))))))))
(stream f fx 3)
Your code is this (I've applied indentation to make the bracketing clearer):
(define (stream f fx x)
(let ((x (3))
((f x) (sin x))
((fx x) (cos x)))
(cons-stream (x (stream f fx (x (- x (/ (f x) (fx x))))
))
)))
(stream f fx 3)
You have a few mistakes in this:
(3) treats 3 as a procedure and tries to call it. You should have 3 instead.
You have put specific arguments 3, sin, cos inside the general function. It should be outside instead.
You have done (x (stream ...)) and (x (- x ..)) both treat x like a function, but it's a number.
So clearing up these mistakes the code will be more like this:
(define (stream f fx x)
(cons-stream x (stream f fx (- x (/ (f x) (fx x))))))
(let ((x 3)
(f (lambda (x) (sin x)))
(fx (lambda (x) (cos x))))
(stream f fx x))
lambda was used to define a local function. Hope that helps, Feel free to ask follow up questions if anything was unclear.

Recursively differentiating basic expression

If I have an expression, such as x * x * x, stored in a data structure like: mult(var x, mult(var x, var x))
And I want to implement a function to recursively differentiate the equation (so to 3 * x * x or x*x + (x + x)*x etc, no simplification required), any suggestions how to being this?
You would find a matching differentiation rule and apply it. For example in this case we have the rule (where A and B stand for whole subexpressions)
diff(mult(A, B)) -> add(mult(diff(A),B), mult(A, diff(B)))
The left hand side of this rule matches the formula when we set
A = var x
B = mult(var x, var x)
So we can apply this rule to the formula and get
diff(mult(var x, mult(var x, var x))) ->
add(mult(diff(var x),mult(var x, var x)), mult(var x, diff(mult(var x, var x))))
Now do the same recursively for the remaining diff operations.
The other other rule you will need here is:
diff(var x) -> 1
Just a note to point out that language can make difference. Lisp is particularly good for this problem.
(defun d (f x)
(etypecase f
(number 0)
(symbol (if (eq f x) 1 0))
(list (df (first f) (rest f) x))))
(defun df (op args x)
(let ((a (first args))
(b (second args)))
(case op
((+ -) `(,op ,(d a x) ,(d b x)))
(* `(+ (* ,a ,(d b x)) (* ,(d a x) ,b)))
(/ `(/ (- (* ,(d a x) ,b) (* ,a ,(d b x))) (^ ,b 2)))
(^ `(* (* ,b (^ ,a ,(1- b))) ,(d a x)))
(sin `(* (cos ,a) ,(d a x)))
(cos `(* (- (sin ,a)) ,(d a x))))))
Lisp likes prefix notation. This is equivalent to an abstract syntax tree for expressions. Binary operations look like (op lhs rhs). So to differentiate (3 sin(x^2))^2,
> (d '(^ (* (sin (^ x 2)) 3) 2) 'x)
(* (* 2 (^ (* (SIN (^ X 2)) 3) 1))
(+ (* (SIN (^ X 2)) 0) (* (* (COS (^ X 2)) (* (* 2 (^ X 1)) 1)) 3)))
This is a correct answer, but clearly it's far from simple form. So the next step is to add an expression simplifier. With a very rudimentary one,
> (simplify (d '(^ (* (sin (^ x 2)) 3) 2) 'x))
(* (* 2 (* (SIN (^ X 2)) 3)) (* (* (COS (^ X 2)) (* 2 X)) 3))
With infix notation, this is 2(3 sin(x^2)) (3 cos(x^2) (2x)). Obviously more simplification is possible, but getting to "most simple" by any useful definition is a complicated topic.

Recursive function not working as planned

I am writing a function in Scheme that is supposed to take two integers, X and Y, and then recursively add X/Y + (X-1)/(Y-1) + ...until one of the numbers reaches 0.
For example, take 4 and 3:
4/3 + 3/2 + 2/1 = 29/6
Here is my function which is not working correctly:
(define changingFractions (lambda (X Y)
(cond
( ((> X 0) and (> Y 0)) (+ (/ X Y) (changingFunctions((- X 1) (- Y 1)))))
( ((= X 0) or (= Y 0)) 0)
)
))
EDIT: I have altered my code to fix the problem listed in the comments, as well as changing the location of or and and.
(define changingFractions (lambda (X Y)
(cond
( (and (> X 0) (> Y 0)) (+ (/ X Y) (changingFunctions (- X 1) (- Y 1) )))
( (or (= X 0) (= Y 0)) 0)
)
))
Unfortunately, I am still getting an error.
A couple of problems there:
You should define a function with the syntax (define (func-name arg1 arg2 ...) func-body), rather than assigning a lambda function to a variable.
The and and or are used like functions, by having them as the first element in a form ((and x y) rather than (x and y)). Not by having them between the arguments.
You have an extra set of parens around the function parameters for the recursive call, and you wrote changingFunctions when the name is changingFractions.
Not an error, but don't put closing parens on their own line.
The naming convention in Lisps is to use dashes, not camelcase (changing-fractions rather than changingFractions).
With those fixed:
(define (changing-fractions x y)
(cond
((and (> x 0) (> y 0)) (+ (/ x y) (changing-fractions (- x 1) (- y 1))))
((or (= x 0) (= y 0)) 0)))
But you could change the cond to an if to make it clearer:
(define (changing-fractions x y)
(if (and (> x 0) (> y 0))
(+ (/ x y) (changing-fractions (- x 1) (- y 1)))
0))
I personally like this implementation. It has a proper tail call unlike the other answers provided here.
(define (changing-fractions x y (z 0))
(cond ((zero? x) z)
((zero? y) z)
(else (changing-fractions (sub1 x) (sub1 y) (+ z (/ x y))))))
(changing-fractions 4 3) ; => 4 5/6
The trick is the optional z parameter that defaults to 0. Using this accumulator, we can iteratively build up the fractional sum each time changing-fractions recurses. Compare this to the additional stack frames that are added for each recursion in #jkliski's answer
; changing-fractions not in tail position...
(+ (/ x y) (changing-fractions (- x 1) (- y 1)))

"Ill-formed clause" issue, mit-scheme

Trying some Lisp, using mit-scheme.
(define (inv curstate x y)
((cond (= y 1) curstate)
(cond (even? y)
(inv (square curstate) x (/ y 2)))
(else
(inv (* x curstate) x (- y 1)))))
An interpreter error:
Ill-formed clause: curstate
Another version use linear recursion method, so there's a similar error with it.
What to do?
Your syntax for cond is wrong. Here's the same code with a corrected syntax:
(define (inv curstate x y)
(cond ((= y 1) curstate)
((even? y)
(inv (square curstate) x (/ y 2)))
(else
(inv (* x curstate) x (- y 1)))))

Scheme Confusing of Let and Let*

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

Resources