Scheme: Not a procedure (Dr. Racket) - scheme

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

Related

Racket: Trying to subtract numbers, getting list

I'm currently learning Racket/Scheme for a course (I'm not sure what's the difference, actually, and I'm not sure if the course covered that). I'm trying a basic example, implementing the Newton method to find a square root of a number; however, I ran into a problem with finding the distance between two numbers.
It seems that for whatever reason, when I'm trying to apply the subtraction operator between two numbers, it returns a list instead.
#lang racket
(define distance
(lambda (x y) (
(print (real? x))
(print (real? y))
(abs (- x y))
)
)
)
(define abs
(lambda x (
(print (list? x))
(if (< x 0) (- x) x)
)
)
)
(distance 2 5)
As you can see, I've added printing of the types of variables to make sure the problem is what I think it is, and the output of all those prints is #t. So:
In calling distance, x and y are both real.
In calling abs, x is a list.
So, the conclusion is that (- x y) returns a list, but why?
I double-checked with the documentation and it seems I'm using the subtraction operator correctly; I've typed (- 2 5) and then (real? (- 2 5)) into the same REPL I'm using to debug my program (Dr. Racket, to be specific), and I'm getting the expected results (-3 and #t, respectively).
Is there any wizard here that can tell me what kind of sorcery is this?
Thanks in advance!
How about this...
(define distance
(lambda (x y)
(print (real? x))
(print (real? y))
(abs (- x y))))
(define abs
(lambda (x) ;; instead of (lambda x ...), we are using (lambda (x) ...) form which is more strict in binding with formals
(print (list? x))
(if (< x 0) (- x) x)))
Read further about various lambda forms and their binding with formals.

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

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

Scheme how to define var in if condition

I am newbie to Scheme programming and trying to define a var in if condition. For example, I have:
(if (< x y) (define x y) ) ;(GOAL: if x < y, than x=y..)
But I got the error:
let: bad syntax (not an identifier and expression for a binding) in:...
Any ideas how to resolve this, would be greatly appreciated.
p.s. Sorry for my English
Unlike imperative languages you should refrain not use define or set! to update variables where you can avoid it. In some circumstances it's needed, like in generators.
Since you don't have a full code example where you'd like to do this I cannot see what obvious solution is to be used.
The way to store intermediate values if by let or recursion:
;; within the let block x shadows the original x
;; with the smalles of the outer x and y
(let ((x (if (< x y) x y)))
(do-something x))
You can do several intermediates by let*
(let* ((tmp (+ x y))
(tmp2 (* tmp y))) ; tmp is bound here
(do-something-with tmp2)); or tmp and tmp2
You you can use recursion, where you update cur and lst in th innner procedure by recursion:
(define (mmin x . xs)
(define (min-aux cur lst)
(cond ((null? lst) cur)
((<= cur (car lst)) (min-aux cur (cdr lst)))
(else (min-aux (car lst) (cdr lst)))))
(min-aux x xs)) ; start recursion
It is an error to define something that is already defined so thats why I defined
If you need to do this top level you can:
(define min_xy (if (< x y) x y))
min_xy. To alter a binding destructively (get it to reference another value) you can use set!
(set! x (+ x 1)) ; increases x
You'll alter the most local definition and it's an error if it doesnæt already exist. This can be used for creating generators:
(define (generator start alter-proc)
(lambda () ; returns a procedure taking 0 arguments
(let ((old start)) ; temporary store what start points to
(set! start (alter-proc start)) ; change what the local start points to
old))) ; return the old value
(define counter (generator 1 (lambda (x) (+ x 1))))
(counter) ; ==> 1
(counter) ; ==> 2
(define doubler (generator 1 (lambda (x) (* x 2))))
(doubler) ; ==> 1
(doubler) ; ==> 2
(doubler) ; ==> 4
Using define is wrong; you are not defining a function here. There are two solutions:
(if (< x y) (set! x y) (void)) ; if x < y set x = y; else do nothing
Or
(set! x (if (< x y) y x)) ; sets x to y if (x<y) is true; else sets x to x

Scheme prime numbers

this is possibly much of an elementary question, but I'm having trouble with a procedure I have to write in Scheme. The procedure should return all the prime numbers less or equal to N (N is from input).
(define (isPrimeHelper x k)
(if (= x k) #t
(if (= (remainder x k) 0) #f
(isPrimeHelper x (+ k 1)))))
(define ( isPrime x )
(cond
(( = x 1 ) #t)
(( = x 2 ) #t)
( else (isPrimeHelper x 2 ) )))
(define (printPrimesUpTo n)
(define result '())
(define (helper x)
(if (= x (+ 1 n)) result
(if (isPrime x) (cons x result) ))
( helper (+ x 1)))
( helper 1 ))
My check for prime works, however the function printPrimesUpTo seem to loop forever. Basically the idea is to check whether a number is prime and put it in a result list.
Thanks :)
You have several things wrong, and your code is very non-idiomatic. First, the number 1 is not prime; in fact, is it neither prime nor composite. Second, the result variable isn't doing what you think it is. Third, your use of if is incorrect everywhere it appears; if is an expression, not a statement as in some other programming languages. And, as a matter of style, closing parentheses are stacked at the end of the line, and don't occupy a line of their own. You need to talk with your professor or teaching assistant to clear up some basic misconceptions about Scheme.
The best algorithm to find the primes less than n is the Sieve of Eratosthenes, invented about twenty-two centuries ago by a Greek mathematician who invented the leap day and a system of latitude and longitude, accurately measured the circumference of the Earth and the distance from Earth to Sun, and was chief librarian of Ptolemy's library at Alexandria. Here is a simple version of his algorithm:
(define (primes n)
(let ((bits (make-vector (+ n 1) #t)))
(let loop ((p 2) (ps '()))
(cond ((< n p) (reverse ps))
((vector-ref bits p)
(do ((i (+ p p) (+ i p))) ((< n i))
(vector-set! bits i #f))
(loop (+ p 1) (cons p ps)))
(else (loop (+ p 1) ps))))))
Called as (primes 50), that returns the list (2 3 5 7 11 13 17 19 23 29 31 37 41 43 47). It is much faster than testing numbers for primality by trial division, as you are attempting to do. If you must, here is a proper primality checker:
(define (prime? n)
(let loop ((d 2))
(cond ((< n (* d d)) #t)
((zero? (modulo n d)) #f)
(else (loop (+ d 1))))))
Improvements are possible for both algorithms. If you are interested, I modestly recommend this essay on my blog.
First, it is good style to express nested structure by indentation, so it is visually apparent; and also to put each of if's clauses, the consequent and the alternative, on its own line:
(define (isPrimeHelper x k)
(if (= x k)
#t ; consequent
(if (= (remainder x k) 0) ; alternative
;; ^^ indentation
#f ; consequent
(isPrimeHelper x (+ k 1))))) ; alternative
(define (printPrimesUpTo n)
(define result '())
(define (helper x)
(if (= x (+ 1 n))
result ; consequent
(if (isPrime x) ; alternative
(cons x result) )) ; no alternative!
;; ^^ indentation
( helper (+ x 1)))
( helper 1 ))
Now it is plainly seen that the last thing that your helper function does is to call itself with an incremented x value, always. There's no stopping conditions, i.e. this is an infinite loop.
Another thing is, calling (cons x result) does not alter result's value in any way. For that, you need to set it, like so: (set! result (cons x result)). You also need to put this expression in a begin group, as it is evaluated not for its value, but for its side-effect:
(define (helper x)
(if (= x (+ 1 n))
result
(begin
(if (isPrime x)
(set! result (cons x result)) ) ; no alternative!
(helper (+ x 1)) )))
Usually, the explicit use of set! is considered bad style. One standard way to express loops is as tail-recursive code using named let, usually with the canonical name "loop" (but it can be any name whatever):
(define (primesUpTo n)
(let loop ((x n)
(result '()))
(cond
((<= x 1) result) ; return the result
((isPrime x)
(loop (- x 1) (cons x result))) ; alter the result being built
(else (loop (- x 1) result))))) ; go on with the same result
which, in presence of tail-call optimization, is actually equivalent to the previous version.
The (if) expression in your (helper) function is not the tail expression of the function, and so is not returned, but control will always continue to (helper (+ x 1)) and recurse.
The more efficient prime?(from Sedgewick's "Algorithms"):
(define (prime? n)
(define (F n i) "helper"
(cond ((< n (* i i)) #t)
((zero? (remainder n i)) #f)
(else
(F n (+ i 1)))))
"primality test"
(cond ((< n 2) #f)
(else
(F n 2))))
You can do this much more nicely. I reformated your code:
(define (prime? x)
(define (prime-helper x k)
(cond ((= x k) #t)
((= (remainder x k) 0) #f)
(else
(prime-helper x (+ k 1)))))
(cond ((= x 1) #f)
((= x 2) #t)
(else
(prime-helper x 2))))
(define (primes-up-to n)
(define (helper x)
(cond ((= x 0) '())
((prime? x)
(cons x (helper (- x 1))))
(else
(helper (- x 1)))))
(reverse
(helper n)))
scheme#(guile-user)> (primes-up-to 20)
$1 = (2 3 5 7 11 13 17 19)
Please don’t write Scheme like C or Java – and have a look at these style rules for languages of the lisp-family for the sake of readability: Do not use camel-case, do not put parentheses on own lines, mark predicates with ?, take care of correct indentation, do not put additional whitespace within parentheses.

Resources