The problem this time is to get the median of three values (easy)
I did this:
(define (med x y z) (car(cdr(x y z)))
and it was accepted but when testing it:
(med 3 4 5)
I get this error:
Error: attempt to call a non-procedure
(2 3 4)
And when entering letters instead of number i get:
(md x y z)
Error: undefined varia
y
(package user)
Using something besides x y z I get:
(md d l m)
Error: undefined variable
d
(package user)
the question was deleted dont know how anyway
write a function that return the median of 3 values
Sorry for editing the question I got that I should put the values in order first not just a sill car and cdr thing so I did so
33> (define (med x y z)
(if(and(
(<x y) (<y z) y
if(and(
(<y x) (<x z) x z)))))
Warning: invalid expression
(if (and< (<x y) (<y z) y if (and ((<y x) (<x z) x z))))
but as u see Im getting a warning so what is wronge ?
You probably want to create a list, like this:
(define (med x y z) (car(cdr(list x y z)))
However, it seems like a waste to bundle up the values into a list just to undo them again. This would have the same effect:
(define (med x y z) y)
Note that as defined, (med . rest) is equivalent to (cadr rest) (except that med only takes three values). Personally, I would expect a function that's supposed to return the median of values to return, well, the median, regardless of list order. For example, (med 4 2 5) would return 4 and (3 0 9 6 5) would return 5.
As for the syntax error (which doesn't matter so much for writing med, since there is a better way using sort, length and list-ref), you don't have your parentheses in the right spots. Here's another way of writing what you have now, lining up terms with their siblings and to the right of their ancestors:
(if (and (
(<x y)
(<y z)
y
if
(and (
(<y x)
(<x z)
x
z
) ) ) ) )
The format for if is:
(if test-expr true-expr false-expr)
All of your terms are sub-terms of the conditional, and there's no true-expr or false-expr. You'd want to write your code as:
(if (and ...)
y
(if (...) ; we know that (not (and (< x y) (< y z))
x
z))
Note that you might be ably to simplfy the later tests, since you know the earlier tests are false.
You could also use a cond, which is clearer than a nested sequence of ifs:
(cond (test result)
(test result)
(test result)
... )
For your code, it would be:
(cond ((and ...) y)
((...) x)
(else z))
There's nothing too special about else (it's a syntactical construct rather than an expression, not that it matters much). You can use any value that evaluates to true (e.g. #t) instead.
Remember, parentheses surround both the function and arguments in Lisp ((foo 1 2 3), not foo(1, 2 ,3)), unlike mathematical notation where parentheses surround just the arguments.
while outis did a pretty good job of explaining the issue, there's one other important bit you need to know
(<x y)
calls the function named <x with the parameter y. you need to make sure you add a space inbetween the < and the x, like so:
(< x y)
Related
I'm trying to run this line in Scheme:
(let ((x y) (y x)) (set! x x) (set! y y))
where at the start of the program x is defined to be 1 and y is defined to be 2.
I want the output to be x=2 and y=1 but I get x=1 and y=2
Appreciate your help!
My end goal is to switch their values only with commands, not with temporary variables
It looks like racket supports set!-values, so you can swap your variables without using any explicit temporary variables like so:
(define x 1)
(define y 2)
(set!-values (x y) (values y x))
;;; x is now 2 and y is 1
(It's even the example in the linked documentation)
In this expression:
(set! x x)
Both x reference the same variable, the one introduced by the let binding. Any change you do to x inside the let (and here, the actual value is unchanged) is not visible outside the let, because outside the let the x symbol is bound to another variable.
If you rename your temporary variables a and b for example:
(let ((a y) (b x)) (set! x a) (set! y b))
You will observe a different behaviour.
(Details of my miniKanren in Racket setup appear at the bottom[1].)
The way quotes and unquotes work in The Reasoned Schemer appears not to match the way they work in Racket. For instance, verse 2 of chapter 2 suggests[2] the following function definition:
(run #f
(r )
(fresh (y x )
(== '(,x ,y) r )))
If I evaluate that, I get '((,x ,y)). If instead I rewrite it as this:
(run #f
(r )
(fresh (y x )
(== (list x y) r)))
I get the expected result, '((_.0 _.1)).
This might seem like a minor problem, but in many cases the required translation is extremely verbose. For instance, in exercise 45 of chapter 3 (page 34), the book provides, roughly[3] the following definition:
(run 5 (r)
(fresh (w x y z)
(loto (('g 'g) ('e w) (x y) . z))
(== (w (x y) z) r)))
In order to get the results they get, I had to rewrite it like this:
(run 5 (r)
(fresh (w x y z)
(loto (cons '(g g)
(cons (list 'e w)
(cons (list x y)
z))))
(== (list w (list x y) z)
r)))
[1] As described here, I ran raco pkg install minikanren and then defined a few missing pieces.
[2] Actually, they don't write precisely that, but if you heed the advice in the footnotes to that verse and an earlier verse, it's what you get.
[3] Modulo some implicit quoting and unquoting that I cannot deduce.
Use the backquote ` instead of the simple quote ' you have been using.
I've started out with SICP and I'm new to Scheme. I've tried debugging this piece of code and even compared it to similar solutions.
(def (myFunc x y z)
(cond ((and (<= x y) (<= x z)) (+ (* y y) (* z z)))
((and (<= y x) (<= y z)) (+ (* x x) (* z z)))
(else (+ (* x x) (* y y)))))
This function returns the sum of the squares of two largest numbers.
When I run this, the interpreter gives out ";Unbound variable: y". Could you please explain the cause behind this error?
Help is greatly appreciated :)
The function-defining primitive in Scheme is called define, not def.
As it is, the whole (def ...) expression was treated as a function call to def. So its arguments' values needed to be found. The first argument (myFunc x y z) is a function call so its argument values needed to be found. Apparently your implementation wanted to find out the value of y first.
The R5RS standard says "The operator and operand expressions are evaluated (in an unspecified order) and the resulting procedure is passed the resulting arguments."
It is likely your implementation chooses the rightmost argument first, which leads to (<= x y) being evaluated first (because of special rules of evaluating the cond and and special forms), with y in its rightmost position.
Write a Scheme procedure named 'proc4' which takes 2 procedures as arguments (w,x) [note that w and x can be expected to work correctly when given two numbers as arguments]
and returns a procedure which takes 2 numbers (y,z) as arguments and returns the
procedure (w or x) which results in the greatest number when applied to y and z
(i.e. in C++ pseudocode if ((y w z) > (y x z)) {return w; } else {return x;} )
So I started
(define proc4(lamdda ( w x) (lambda y z)...
Then I wanted to do the if part. Something like
(if (> (apply w ( y z)) (apply x( w z))) but I keep getting errors.
I've been trying to find help on internet but everything I've seen so far does not make sense to me.
You can invoke function objects directly, without using apply:
(define (proc4 f g)
(lambda (x y)
(if (> (f x y) (g x y))
f
g)))
A bit of syntactic sugar for #ChrisJester-Young's answer - you can declare a procedure that returns another procedure like this:
(define ((proc4 f g) x y)
(if (> (f x y) (g x y))
f
g))
In the above code, the first procedure receives as parameters the procedures f and g, and in turn returns a procedure that receives as parameters x and y. We know that f and g are procedures because the way they're used inside the body of the definition, but they can have any name you want. Of course you can call the procedure in the usual way:
((proc4 + *) 10 20)
=> #<procedure:*>
The point of interest in this example is that procedures can also be passed as parameters (and returned as values), you don't need to apply them, just invoke the procedures received as parameters as you would with any other procedure. Also notice that all the answers to this question are equivalent, but the short-hand syntax that I'm using might not be available in all interpreters.
I cannot make much sense of this (obviously homework) question but I'd go for this:
(define proc4
(lambda (w x)
(lambda (y z)
(if (> (w y z) (x y z))
w
x))))
I have this piece of scheme code:
(define (x . y) y)
(x 1 2 3)
and I know it equivalent to:
'(1 2 3)
But i can't understand why.
What does the first line of code do?
Thank you.
The first line (define (x . y) y) is equivalent to (define x (lambda y y)), according to 5.2 Definitions(the last clause).
And (lambda y y) is a procedure; when called all the arguments will stored in a newly allocated list. e.g. list could be defined as (define list (lambda xs xs)). (See 4.1.4 Procedures the second form of formal parameters.)
So (x 1 2 3) is equivalent to (list 1 2 3).