SICP 1.3 interpreter error unknown identifier: and - scheme

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

Related

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: Not a procedure (Dr. Racket)

I'm running this program in Dr. Racket using R5RS scheme and am getting this error on the line (+ 1 IntDivide((- x y) y)):
"application: not a procedure; expected a procedure that can be
applied to arguments given: 5 arguments...:"
The procedure is supposed to return the quotient of the division between two integers using subtraction. Since this is a homework problem, I'm not going to ask whether my solution is correct (I can debug that later), but rather what is causing this error. It seems to be commonly caused by excess brackets, but I can't seem to find them. Any help would be appreciated.
(define IntDivide (lambda (x y)
(if (eqv? (integer? x) (integer? y))
(begin
(if (= y 0)
(begin
(write "Can't divide by zero") (newline)
-1
)
)
(if (= (- x y) 0)
1
)
(if (< x y)
0
)
(if (> x y)
(+ 1 IntDivide((- x y) y))
)
)
)
(write "Please only input integers")
))
Thanks in advance!
In addition to moving the operator inside the parens, you also need to replace the if with a cond:
(define IntDivide
(lambda (x y)
(if (eqv? (integer? x) (integer? y))
(cond ((= y 0) (write "Can't divide by zero")
(newline)
-1)
((= x y) 1)
((< x y) 0)
((> x y) (+ 1 (IntDivide (- x y) y))))
(write "Please only input integers"))))
The way you have it now, with the interior if expressions, won't work because they don't automatically return. They just evaluate and then the result gets thrown away.
Call IntDivide the same way you would any other function.
(+ 1 (IntDivide (- x y) y))

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

removing nested lambdas from function definition

I have to remove every lambda from the following code, and I can't use other functions in the global space. (((f 1) 2) 3) should produce 6.
(define f (lambda (x)
(lambda (y)
(lambda (z)
(+ x y z)))))
I have tried using define in define, but the problem is with the (((f 1) 2) 3) having to give 6. I dont see how I can use the 2 and 3 inside function f, if they are given outside the function? It is OK if the lambdas are “under the hood,” they just have to not be visible.
Try
(define (f x)
(define (g y)
(define (h z)
(+ x y z))
h)
g)
or
(define (((f x) y) z)
(+ x y z))

Resources