count change SICP - scheme

I was reading the SICP and encountered with a problem, in chapter 1 there is an example named counting change, I need to write a program in scheme to calculate the possible number of ways to make a change of any given number given half-dollars, quarters, dimes, nickles and pennies.
the book shows a substitution model of program and I tried to change it to a nesting one but failed, could anyone give me a favor?
(define (count_change total_amount)
(define (denomination kinds_of_coins)
(cond ((= kinds_of_coins 5) 50)
((= kinds_of_coins 4) 25)
((= kinds_of_coins 3) 10)
((= kinds_of_coins 2) 5)
((= kinds_of_coins 1) 1)))
(define (cc amount kinds_of_coins)
(cond (= amount 0) 1)
((or (< amount 0) (= kinds_of_coins 0)) 0)
(else (+ (cc amount (- kinds_of_coins 1))
(cc (- amount (denomination kinds_of_coins)) kinds_of_coins))))
(cc total_amount 5))
the execution result is as follows:
;Ill-formed clause: 1

A cond expression generally takes the form (cond (predicate expr) ... (else expr)) or (cond (predicate expr) ... (#t expr)). Whenever a predicate evaluates to true, the correspondent expression in the clause is the result of the conditional expression. If you do not have an else/#t predicate at the end and all of the predicates on the conditional expression are false, generally the expression returns a void value.
Here, you have a syntax error because you did not started a clause properly. So, instead of having (cond (= amount 0) 1) you should have (cond ((= amount 0) 1) ...).

Related

with-syntax: binding match failed - Scheme error?

I'm not sure what's going wrong here, I believe my syntax is correct but I've no idea what the error is trying to say.
(define (even-nm-inst? n)
(cond ((= n 2) #t)
((= n 4) #t)
((= n 6) #t)
((= n 8) #t)
((= n 10) #t)
((> n 2)
(modulo n 2)
(cond ((= n 0) #t)
(cond ((= n 1) #f)
((< n 2)
(modulo n 2)
(cond ((= n 0) #t)
((= n 1) #f)
)))))))
I'm trying to make a function that determines if a number is even or not.
The specific error returned is:
. ../../Applications/Racket v6.6/share/pkgs/r5rs-lib/r5rs/main.rkt:493:22: with-syntax: binding match failed in: (_ . rest)
Any idea what's going on? I know it's this specific part of code because I have headers on the different sections, and the error appears under the header for this chunk.
Thanks in advance, I'm brand new to scheme.
No, that's not correct – your conds are all over the place, and apparently so much so that Racket is getting confused.
It's not clear at all why you wrote all that code;
(define (even-nm-inst? n)
(= (modulo n 2) 0))
would do, as would using even?.
Well, this is an inexcusably bad syntax error...
but on the other hand, it looks like you're using the extremely-legacy R5RS language. If that's because you're in a class and your instructor requires it, then you're stuck with it. If not, though, you should definitely switch ASAP to the main Racket language, or the Beginning Student language; neither of them should give you that terrible message.
Specifically, in the Beginning Student language, you'll get this message:
"cond: expected a clause with a question and an answer, but found a clause with 3 parts" ... and it highlights the three parts of the clause that are the problem.
Since you are using DrRacket why don't you press CTRL+i and it will format the code according to what you have written and not what you would like to have written. THe result is:
(define (even-nm-inst? n)
(cond ((= n 2) #t)
((= n 4) #t)
((= n 6) #t)
((= n 8) #t)
((= n 10) #t)
((> n 2)
(modulo n 2) ; doesn't do anything since result not used
(cond ((= n 0) #t)
(cond ((= n 1) #f) ; cond doesn't exist as a variable
((< n 2)
(modulo n 2)
(cond ((= n 0) #t) ; cond doesn't exist as a variable
((= n 1) #f)
)))))))
Now. If using even? is not an option I would have written this:
(define (my-even? n)
(cond ((negative? n) (my-even? (- n)))
((zero? n) #t)
((= n 1) #f)
(else (my-even? (- n 2)))))
(my-even? -5) ; ==> #f
(my-even? 10) ; ==> #t
You use modulo and it can be used to produce a result without any conditionals:
(define (my-even? n)
(= 0 (modulo n 2)))

How cond works in Scheme?

(define (list-ref items n)
(cond ((null? items) "Out of range exception")
((= n 0) (car items))
(list-ref (cdr items) (- n 1))))
(list-ref (list 1 2 3) 6)
5
Why it always return value of (- n 1)? Why it doesn't execute (list-ref (cdr items) (- n 1)) ?
You forgot an else in the final clause.
Instead, it used list-ref as the condition (which is always truthy, since all procedures are truthy), and evaluated your other two subforms and returned the last one.

Issues with conditionals in Scheme

I'm using Scheme with the full Swindle package, and I'm trying to use conditionals to recursively determine evenness/oddity of integers. My code is as follows:
(define (odd? x)(
(cond
((= x 0) '#f)
((= x 1) '#t)
((= (even? (- x 1)) #t) '#f)
(else '#t))))
(define (even? x)(
(cond
((= x 0) '#f)
((= x 2) '#t)
((= (odd? (- x 1)) #t) '#f)
(else '#t))))
However, when I run (even? x) or (odd? x) [x is some number, doesn't matter what, as I get the same error] I get: application: not a procedure;
expected a procedure that can be applied to arguments
given: #t
arguments...: [none]
Can anyone help? Thanks. I'm not 100% familiar with ideal Scheme syntax, so it might be that.
You have an erroneous pair of parentheses surrounding the cond expression (that's causing the error reported). But also, there are way too many conditions in each procedure, and because you're using = to compare numbers with boolean values, there will be a point where a contract violation will occur. For fixing that you can replace = with equal? in here:
((equal? (even? (- x 1)) #t) '#f)
And in here:
((equal? (odd? (- x 1)) #t) '#f)
But then, the procedures will still give an incorrect result:
(even? 5)
=> #t
(odd? 7)
=> #f
Honestly, I think it'd better to simplify the implementation, that will solve all the problems. Try this instead:
(define (odd? x)
(cond ((= x 0) #f)
(else (even? (- x 1)))))
(define (even? x)
(cond ((= x 0) #t)
(else (odd? (- x 1)))))
Now we'll get correct answers:
(even? 4)
=> #t
(even? 5)
=> #f
(odd? 6)
=> #f
(odd? 7)
=> #t
Any Scheme form in parentheses is an application, like (sin 42) or (42 sin). The first calls sin as a function with argument 42 and produces a value; the second tries to call 42 with an argument sin, but 42 is no procedure, so this causes an error. Similarly (42) is an application with no arguments; still it must have a procedure to be applied as its first part, to be called with no arguments, right? In Scheme, parentheses matter, they are not just for grouping stuff (as they may be in some other languages). So the extra parentheses cause an extra attempt to evaluate the result, which is a Boolean, i.e. not a procedure, so this is an error.
Then, '#f is just #f; similarly for #t (they both evaluate to themselves); and a condition (= test #t)1 (equal? test #t) is the same as just test (produces the same set of Boolean results) ((1 we can't use = to compare Booleans, it is supposed to be used with numbers only)):
(define (odd? x)
(cond
((= x 0) #f)
((= x 1) #t)
((even? (- x 1)) #f)
(else #t)))
Also, (if test #f else...) is the same as (if (not test) else... #f):
(define (odd? x)
(cond
((= x 0) #f)
((= x 1) #t)
((not (even? (- x 1))) #t)
(else #f))) ; (else ...) is like (#t ...)
using logical connectives, the clauses with the same outcome can be merged, and mutually exclusive clauses can be rearranged (mutual exclusivity can be achieved with explicit guards):
(define (odd? x)
(cond
((and (/= x 0) ; a guard
(or (= x 1)
(not (even? (- x 1))))) #t)
((or (= x 0) #t) #f)))
but (cond (test #t) (else #f) is (if test #t #f) which is just test:
(define (odd? x) (and (> x 0) ; `>` is better
(or (= x 1)
(not (even? (- x 1))))))
The guard (> x 0) prevents the fall-through for negative xes.
But then, this is completely wrong. For n to be odd, n-1 must be even, not the opposite!
(define (odd? x) (and (> x 0) ; work only for positive integers
(or (= x 1)
(even? (- x 1)))))
We could write (not (odd? (- x 1))), but then it wouldn't be tail recursive. It would be tail recursive modulo cons (not serving as a "constructor"), but for some historic fluke of a reason2, TRMC optimization isn't required of a Scheme implementation. The last expression in and and or forms is, in fact, in tail position. But not in not. ((2 despite being described as early as 1974.))
Repeat the same for your definition of even?.

Scheme doing more than one job in one if condition

I am trying to do more than one task in one if condition, here is my code:
(define (dont-tolerate-fools hist0 hist1 hist2 count)
(cond ((> 10 count) 'c)
((< 10 count) (soft-tit-for-tat hist0 hist1 hist2))
((> 10 count) (dont-tolerate-fools hist0 hist1 hist2 (+ 1 count)))))
It didn't work, because I saw that one of the conditions is true it returns it and break. I am trying to make it return 'c for the first 10 time after that it should behave according to something else.
There may be different ways to do it, but I am interesting in how can I do 2 jobs by checking only one if condition?
Thanks in advance.
If you want to do something for the first 10 times you are called, then something else afterwards, the easiest way is to have some kind of "local" variable to count how many times you've been called, such as:
(define func
(let ((count 0))
(lambda ()
(cond
((< count 10)
(set! count (+ count 1))
'a)
(else 'b)))))
(for/list ((i (in-range 15)))
(func))
=> '(a a a a a a a a a a b b b b b)
You can also see in that example that you can have multiple forms or values after the condition:
(cond
((< count 10)
(set! count (+ count 1)) ; action 1
'a) ; action 2
OTOH, if this was simply supposed to be a loop then you're missing a stop condition and one call:
(define (func (n 0))
(cond
((> n 15)
'stop)
((< n 10)
(display 'c)
(func (+ n 1)))
(else
(display 'x)
(func (+ n 1)))))
(func)
=> ccccccccccxxxxxx'stop
The syntax of cond is:
(cond (<predicate> <body> ...)
...)
where <body> ... means that any number of expressions. So you can simply rewrite your code as:
(define (dont-tolerate-fools hist0 hist1 hist2 count)
(cond ((> 10 count)
(dont-tolerate-fools hist0 hist1 hist2 (+ 1 count))
'c)
((< 10 count) (soft-tit-for-tat hist0 hist1 hist2))))

how to check if a number is power of two in Scheme by tail recursion?

(define (ispowerof2? n)
(cond ((< n 1) #f)
((= n 1) #t)
((> (remainder n 2) 0) #f)
(else (ispowerof2? (/ n 2)))))
Is this code correct and how to write the same function with tail recursion?
I agree with the other two answers. To explain a bit more deeply: a "tail-recursive" function is one where all recursive calls are in tail position. This begs the question of what constitutes a tail call.
One way to see the tail calls is to run this function using DrRacket's stepper. In particular, set the langage level to "Beginning Student" and click the "step" button on this program:
(define (ispowerof2? n)
(cond
((< n 1) false)
((= n 1) true)
((> (remainder n 2) 0) false)
(else (ispowerof2? (/ n 2)))))
(ispowerof2? 36)
... then step forward until you get to a recursive call:
(define (ispowerof2? n)
(cond
((< n 1) false)
((= n 1) true)
((> (remainder n 2) 0) false)
(else (ispowerof2? (/ n 2)))))
(ispowerof2? (/ 36 2))
Note that the recursive call is at the top level; there's no "context" wrapping it, with code to be applied to the result of the call. This is what is meant by a "tail call". Contrast this with a function that computes the length of a list:
(define (len l)
(cond
((empty? l) 0)
(else (+ 1 (len (rest l))))))
(len (cons 3 (cons 4 empty))
Step forward until you get a recursive call, and you'll see this:
(define (len l)
(cond
((empty? l) 0)
(else (+ 1 (len (rest l))))))
(+ 1 (len (list 4)))
See how the recursive call to 'len' is inside of a (+ 1 ...) expression? That's because this call is not in tail position; there are still more expressions to evaluate in this function after the return of the recursive call.
Not quite. The line:
(else (ispower2? (/ n 2)))))
Contains an error - it should be ispowerof2. Otherwise, this is tail recursion.
Yes, this is tail recursive. :)

Resources