Scheme The object is not applicable - scheme

(define (min2 a b)
(if (> a b)
b
a))
(define (min3 x y z)
(min2 (min2 x y) (min2 y z)))
(define (sum x y z)
(- (+ x y z) min3(x y z)))
(sum 1 2 3)
error tip: ;The object 1 is not applicable.
Scheme Newbie learn Scheme, So I don't understand why (min3 1 2 3) is right, but (sum 1 2 3) is wrong?

You had min3 in the wrong place in the definition of sum:
(define (sum x y z)
(- (+ x y z) (min3 x y z)))

Related

SICP 1.3 interpreter error unknown identifier: and

I am using the interpreter from browser (without any local setup): https://inst.eecs.berkeley.edu/~cs61a/fa14/assets/interpreter/scheme.html
and getting the following interpreter exception message:
SchemeError: unknown identifier: and
Current Eval Stack:
-------------------------
0: and
1: (cond (and (< x y) (< x z)) (sqrt-sum y z))
2: (f 1 2 3)
for the following code:
; define a procedure that takes three numbers
; as arguments and returns the sum of the squares
; of the two larger numbers
(define (square) (* x x))
(define (sqrt-sum x y)
(+ (square x) (square y)))
(define (f x y z)
(cond (and (< x y) (< x z)) (sqrt-sum y z))
(cond (and (< y x) (< y z)) (sqrt-sum x z))
(cond (and (< z y) (< z x)) (sqrt-sum x y)))
(f 1 2 3)
I am struggling to find any info about specific Scheme version this interpreter is based on; sorry
That's not the correct syntax for cond. The syntax is
(cond (condition1 value1...)
(condition2 value2...)
...)
In your code the first condition should be the expression (and (< x y) (< x z)). But you don't have the parentheses around the condition and value. You have just and where the condition should be, not (and (< x y) (< x z)). Since and isn't a variable with a value, you get an error because of that.
The correct syntax is:
(define (f x y z)
(cond ((and (< x y) (< x z)) (sqrt-sum y z))
((and (< y x) (< y z)) (sqrt-sum x z))
((and (< z y) (< z x)) (sqrt-sum x y))))

Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers

I'm having trouble figuring out how to sort out the 2 biggest numbers and return them into the sum of squares procedure. I am struggling to write the code out in Scheme's syntax. I'm trying to write it as cleanly as possible, and I keep running circles in my head and on paper trying to do so. the book describes thinking "procedurally" and I think I'm having trouble with that aspect.
The book provides code for the sum-of-squares and square procedures. I would include my pseudo code but I'm severely lost. Here is the code the book provides:
(define (square x) (* x x))
(define (sum-of-squares x y)
(+ (square x) (square y)))
How to define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers?
How to define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers?
First you need a name for the procedure. Let's called it sum-of-squares-two-largest.
(define (sum-of-squares-two-largest x y z)
...)
It can make use of the sum-of-squares function, but it needs to find the two largest numbers out of x,y,z first.
One way to do this would be to get rid of the smallest number. You could define a helper procedure smallest? a b c that checks that a is the smallest of the 3 numbers by doing (and (<= a b) (<= a c)).
(define (sum-of-squares-two-largest x y z)
(if (smallest? x y z)
(sum-of-squares y z)
(if (smallest? y x z)
...]
Write the code for min-of-three. Its negative (as in photography) is what you need:
(define (negative-min-of-three a b c)
(if (<= a b)
(if (<= a c)
(..... b ... c .....)
(..... a ... b .....))
(if (<=
..........
You can complete the code, and rename it. The clock is ticking!
I created two methods to get the largest and the one in the middle for the time being.
(define (largest x y z)
(cond ((and (> x y) (> x z)) x)
((and (> y x) (> y z)) y)
(else z))
)
(define (mid x y z)
(cond ((and (> x y) (< x z)) x)
((and (> y x) (< y z)) y)
(else z))
)
(define (square a)
(* a a)
)
(define (sum-of-two-largest x y z)
(+ (square (largest x y z)) (square (mid x y z)))
)
(sum-of-two-largest -12 -4 1)
The hard part of this is, if you're reading SICP book, finding the 2nd largest number of the three. You can observe, if we let c < b < a, that:
a = max(a, b) gives the largest of the two numbers
b = max(c, b) gives the largest of the two smaller numbers
But how do we get the variable b on the second line. It can so happen that a is the smaller of the two? We can observe that:
b = min(a, b)
If we substitute min(a, b) for b in the max function on the third line, we get:
b = max(c, min(a, b))
This strategy is implemented in the following code, using only the constructs introduced in the book so far:
(define (square x) (* x x))
(define (max a b) (if (> a b) a b))
(define (min a b) (if (< a b) a b))
(define (sum-of-squares-two-largest a b c)
(+ (square (max a b)) (square (max c (min a b)))))
(sum-of-squares-two-largest 1 2 3)
(sum-of-squares-two-largest 1 2 1)

Output of function will not change

I have asked an earlier question regarding how to set-up my function based on the requirements in the problem, and using already the code I had written, the problem now is that, no matter what, the output stays the same, no matter how much I change the value of the parameter k in first-value-k-or-higher x tol 1.
Here is my code based on the feedback in my other question:
(define (square x)
(* x x))
(define (first-value-k-or-higher x tol k)
(if (<= (abs(- x
(square (babylonian x k))))
tol)
k
(first-value-k-or-higher x tol (+ k 1))))
(define (terms-needed x tol)
(first-value-k-or-higher x tol 1))
Here is a couple example outputs if the function looks like the one I have above:
> (terms-needed 15 .001)
1
> (terms-needed 234 3)
1
> (terms-needed 23421 453)
1
>
If I change the function terms-needed x tol to something like this:
(define (square x)
(* x x))
(define (first-value-k-or-higher x tol k)
(if (<= (abs(- x
(square (babylonian x k))))
tol)
k
(first-value-k-or-higher x tol (+ k 1))))
(define (terms-needed x tol)
(first-value-k-or-higher x tol 100))
The new function will output:
> (terms-needed 15 .0001)
100
> (terms-needed 243 3)
100
>
Terms-needed is supposed to evaluate to the number of terms in the infinite sum needed to be within tol, that is, the smallest k such that the difference between x and (square (babylonian x k)) is less than tol. As I have mentioned the problem is I keep getting the same output of "1" no matter what I put down for the values of the parameters of terms-needed x tol. I also believe that is where the problem is coming from, because if I change (first-value-k-or-higher x tol 1)) to something like (first-value-k-or-higher x tol 2)) or any other value (first-value-k-or-higher x tol 2)) will output that value, for example with (first-value-k-or-higher x tol 2)) will output 2.
Here is the function babylonian x k that is needed to run the program first-value-k-or-higher x tol k which is needed to run terms-needed x tol:
(define (babylonian x k)
(if (>= x 1)
(if (= k 0)
(/ x 2)
(* (/ 1 2) (+ (expt x (/ 1 2)) (/ x (expt x (/ 1 2))))))
1)
)
The babylonian function is supposed to compute roots using the babylonian method and evaluates to the k^th approximation (Sk). The babylonian function passes all the tests as well.
Here is my earlier problem for more background information
No,
(define (babylonian x k)
(if (>= x 1)
(if (= k 0)
(/ x 2)
(* (/ 1 2) (+ (expt x (/ 1 2)) (/ x (expt x (/ 1 2))))))
1)
)
could not possibly be computing "the k^th approximation" of x, because there's no k in the alternative of the inner if expression.

Scheme Why does it seem that my else statement is not working?

. I am trying to teach my self some computer science skills independently. The problem I am working on wants me to create a way to choose the two biggest numbers out of three then find the sum of squares for the two numbers.
(define (pro x y z)
(cond( (and (< x y) (< x z)) (define a y)(define b z))
( (and(< y x) (< y z)) (define a x) (define b z))
( else ((define a x )(define b y))))
(+ (* a a) (* b b))
When I run the function with z being the smallest or tied for the smallest number I get the following error:
Error: #<undef> is not a function [pro, (anon)]
Why am I getting this error and how do I fix it?
I have been using repl.it to run this program, if that matters.
First, using define's that way is totally bizarre for Scheme code.
After that, I see two problems with the code. The first, the one that's creating the error you're getting, is that you have an extra layer of parens in the else clause. The following
((define a x) (define b y))
is going to evaluate the first define and try to apply it as a procedure. The evaluation of (define ...) returns the #undef which is the source of your error messsage.
If you fixed that problem, your next problem is that your sum of squares code is outside the scope of the defines in your cond and you'll find that a and b are not defined out there.
You should do something like this:
(define (max-of-3 x y z)
(cond
((and (< x y) (< x z)) (values y z))
((and (< y x) (< y z)) (values x z))
(else (values x y))))
(define (pro x y z)
(let-values (((a b) (max-of-3 x y z)))
(+ (* a a) (* b b))))
or even
(define (pro x y z)
(let-values
(((a b) (cond
((and (< x y) (< x z)) (values y z))
((and (< y x) (< y z)) (values x z))
(else (values x y)))))
(+ (* a a) (* b b))))

Scheme let bound statements

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)

Resources