Scheme procedure with 2 arguments - scheme

Learned to code C, long ago; wanted to try something new and different with Scheme. I am trying to make a procedure that accepts two arguments and returns the greater of the two, e.g.
(define (larger x y)
(if (> x y)
x
(y)))
(larger 1 2)
or,
(define larger
(lambda (x y)
(if (> x y)
x (y))))
(larger 1 2)
I believe both of these are equivalent i.e. if x > y, return x; else, return y.
When I try either of these, I get errors e.g. 2 is not a function or error: cannot call: 2
I've spent a few hours reading over SICP and TSPL, but nothing is jumping out (perhaps I need to use a "list" and reference the two elements via car and cdr?)
Any help appreciated. If I am mis-posting, missed a previous answer to the same question, or am otherwise inappropriate, my apologies.

The reason is that, differently from C and many other languages, in Scheme and all Lisp languages parentheses are an important part of the syntax.
For instance they are used for function call: (f a b c) means apply (call) function f to arguments a, b, and c, while (f) means apply (call) function f (without arguments).
So in your code (y) means apply the number 2 (the current value of y), but 2 is not a function, but a number (as in the error message).
Simply change the code to:
(define (larger x y)
(if (> x y)
x
y))
(larger 1 2)

Related

How to create a lambda procedures?

I need to complete an assignment for my college course using Scheme. I've never coded in Scheme before so I have no clue what I'm doing. Our assignment is to define an anonymous function that computes the discriminant of a quadratic function. I keep running into the error: "Invalid `define'. Any help would be appreciated.
(define roots (lambda(abc))(
(lambda(discriminant))(
list(/(+(-b) discriminant)(*2a))
(/(-(-b) discriminant)(*2a))
)
(sqrt - (*bb)(*4ac))
)
First, you should learn a bit about what Scheme code looks like; find some example code (in your textbook, or online, or in answers here on SO) and notice how parentheses and whitespace are used. Then emulate that. You can't arbitrarily place parentheses or arbitrarily remove whitespace in Scheme (or in any Lisp).
For example, in the posted code (-b) gets two things wrong. First, -b is treated as one symbol, not as the negation of the value of b. Further, placing the symbol in parentheses indicates a procedure call; given an s-expression (f x), f is either a syntactic keyword (in which case (f x) is interpreted as a macro call), or (f x) is interpreted as a procedure call. If it is a procedure call and f is not bound to a procedure, then an exception is raised. So (-b) attempts to call a procedure named -b, which does not exist (unless you have defined it), raising an exception. You can use (- b), with a space between the - procedure and the symbol b; this evaluates to the negation of the value of b.
Similarly, *2a is interpreted as a symbol, not an expression; placing the *2a between parentheses is interpreted as a procedure call. The interpreter (or compiler) is expecting that *2a is a procedure which takes no arguments. You need to add the spaces: (* 2 a); this is interpreted as a call to the procedure * with the arguments 2 and a.
(*bb) and (*4ac) have exactly the same problems. The second case is interesting because when it is correctly written it illustrates one of the advantages of prefix notation. Since * is associative, it does not matter what order multiple values are multiplied in. To express naively 4 * a * c in prefix notation you could write (* 4 (* a c)), explicitly ordering the multiplications. You could also write this as (* (* 4 a) c), multiplying in a different order. It does not matter what order you multiply in, so you might as well just write (* 4 a c), so long as your language supports this notation. It turns out that Scheme and other Lisps do support this notation.
Another problem with s-expression notation in the posted code (after fixing the problems noted above): (sqrt - (* b b) (* 4 a c)). This is attempting to call the sqrt procedure on the arguments -, (* b b), and (* 4 a c). But sqrt is not a higher-order procedure (i.e., it does not take procedures as arguments), and it in fact only takes one argument. It was meant to apply the - procedure to the arguments (* b b) and (* 4 a c), subtracting them before taking the square root: (sqrt (- (* b b) (* 4 a c))).
The first lambda expression has a formal parameter list containing only one parameter: abc. As before, this is a mistake. The intention was to define three parameters: don't skimp on spaces: (lambda (a b c)).
The other significant problem is that there are syntax errors in the lambda expressions: (lambda (a b c)) has no body, but a lambda expression must have at least one expression in its body. This was probably intended to wrap the lambda expression which follows. Similarly, the inner lambda expression is missing its body. It was probably intended to wrap the (list ;;...) form that follows.
With that done, the inner lambda expression is itself inside of a pair of parentheses, taking the expression (sqrt (- (* b b) (* 4 a c))) as its argument. This is the lambda form of a let binding. Thus, the inner lambda takes one argument, discriminant, and evaluates the list form that is its body. Since the inner lambda expression itself occurs in the first position of an s-expression, it is part of a procedure call, and this inner anonymous procedure is then called on its argument, binding discriminant to the value obtained by evaluating that argument, which is (sqrt (- (* b b) (* 4 a c))). This all occurs inside of the outer lambda, which takes the three arguments a, b, and c. So, root is a function taking three arguments, and returning a list of roots, after binding the result of the discriminant calculation to discriminant (as a way of both simplifying the expression of the roots and ensuring that the discriminant need only be calculated one time).
Here is the fixed-up code. Note that I only added some spaces and added or moved a few parentheses; nothing else was changed:
(define roots
(lambda (a b c)
((lambda (discriminant)
(list (/ (+ (- b) discriminant) (* 2 a))
(/ (- (- b) discriminant) (* 2 a))))
(sqrt (- (* b b) (* 4 a c))))))
Pay attention to what this looks like. In Lisps you should almost never leave parentheses hanging on lines by themselves, and you should always place a space between arguments. Remember that everything is a procedure call.
Here is a sample interaction. Notice that you can represent negative numbers as -1 instead of (- 1) (you can do either if you wish). You just can't express a negative value using a variable as -b.
> (roots 1 0 -1)
(1 -1)
> (roots 1 8 15)
(-3 -5)

how to use the if statement in scheme programming?

I just started learning the scheme language and below is a question that I stuck a little bit(Is there anything wrong with my code cuz the error message is kinda weird)
Prompt: Define a procedure over-or-under which takes in a number x and a number y and returns the following:
-1 if x is less than y
0 if x is equal to y
1 if x is greater than y
What I've tried so far is :
(define (over-or-under x y)
(if (< x y)
-1)
(if (= x y)
0)
(if (> x y)
1)
)
The error message is :
scm> (load-all ".")
Traceback (most recent call last):
0 (adder 8)
Error: str is not callable: your-code-here
scm> (over-or-under 5 5)
# Error: expected
# 0
# but got
The syntax of if is:
(if condition expression1 expression2)
and its value is the value of expression1 when the condition is true, otherwise it is the value of expression2.
In your function instead you use:
(if condition expression1)
and this is not allowed. Note, moreover that the three ifs one after the other are executed sequentially and only the value of the last one is actually used, as the value returned by the function call.
A way of solving this problem is using a “cascade” of if:
(define (over-or-under x y)
(if (< x y)
-1
(if (= x y)
0
1)))
Note that the proper alignment make clear the order of execution of the different expressions. If (< x y) is true than the value -1 is the result of the if, but, since it is the last expression of the function, it is also the value of the function call. If this is not true, we execute the “inner” if, checking if x is equal to y, and so on. Note also that in the third case is not necessary to check if x is greater than y, since it is surely true, given that x is not less than y, neither equal to y.
Finally, note that the “cascade” of x is so common that in scheme exists a more syntactically convient way of expressing it with the specific cond expression:
(cond (condition1 expression1)
(condition2 expression2)
...
(else expressionN))
so you could rewrite the function is this way:
(define (over-or-under x y)
(cond ((< x y) -1)
((= x y) 0)
(else 1)))

Comparing two lists in scheme

I am trying to recursively compare and output the smallest number in 2 equal sized set of lists. Example (testFunc '(3 5 9) '(1 2 11)) will return '(1 2 9). I have tried the following:
(define (testFunc X Z)
(if (< (car X) (car Z)) ((car X) (testFunc((cdr X) (cdr Z))))
((car Z) (testFunc((cdr X) (cdr Z))))))
My thought process and what I am trying to achieve:
compare the first element of X and Z. If x(1) is smaller than z(1) then print x(1) and drop the first element from both lists using cdr and repeat the process by calling testFunc else print z(1) and do the same thing until we went through each position.
Appreciate all the help in advance. Thanks!
To call testFunc, you must use (testFunc arg1 arg2). You must not use (testFunc(arg1 arg2)). Scheme is parenthesis-sensitive; you must not add (or remove) extra parentheses.
Likewise, to bunch up the results, you need to use (cons item rest), and not just (item rest).
Have you considered using just (map min list1 list2)?
What you want is the k-minor numbers from 2 lists where k is the size of both lists. There are many ways to do this.
Here's one idea:
First append both lists.
Then sort them from lower to higher.
Then take the first three.
But that wouldn't be exactly recursive (sort is recursive but the procedure as such is not).
So another idea uses tail recursion using a list that saves the returning result and we'll name it res and a procedure that gets the minor item from a list called min-list.
Check if length of res is k. If so, return res.
Otherwise let minorA= (min-list A), minorB=(min-list B)
Finally:
if minorA < minor B
recursive call with A=(remove minorA A) B=B, res=(cons minorA res), k=k
else recursive vall with A=A B=(remove minorB B), res=(cons minorB res), k=k
And this idea is in fact recursive.
I got the code written but I want you to try and code it yourself so please tell us of any doubt.
Happy coding!
EDIT:
I've read the comments and it seems you can't use min. Does this mean you cannot use the one that comes in racket/base? If so, you can write your own procedure to check which is the minimal value but if you're not allowed even that, then we'll have to try something else. (I'll post here next idea when I get one).
Oh, and please, clarify the form of the input lists, are they ordered from minor to greater? In your example it seems that way but if it's not always like that then the procedure can change a bit.

Algorithm evaluating user-defined functions

Hello I have some homework that consists of extending a lisp interpreter. We are to build three primitives with pre-evaluated arguments ( for exemple <= ), and three primitives who do their own evaluation ( for example if ).
I went beyond the call of duty and created the only fun function in the bounds of this exercice : (defun) [it's the common lisp keyword for defining a user-function].
I would like to know if my algorithm for managing a user-defined function call is worthwhile.
In pseudo code, here it goes :
get list of parameters # (x y z)
get list of arguments # (1 2 3)
get body of function # (+ x (* y z))
for each parameter, arg # x
body = replace(parameter, argument, body) # (+ 1 (* y z))
# (+ 1 (* 2 z))
# (+ 1 (* 2 3))
eval(body) # 7
Are there better ways to accomplish this?
Thanks.
EDIT: replace() is a function recursing on sub-lists of body.
I never found better, no one proposed better, the question generated no interest whatever, and I'm on a rampage to close my opened questions, so here is the answer :
my algorithm was good enough.

Using conditionals in Scheme

I have to create the following:
A Scheme procedure named 'proc2' which takes 4 numbers as arguments
and returns the value of the largest argument minus the smallest.
So I want to write
(define proc2
lambda(a b c d)
...
)
Is there any way I can evaluate (> a b), (> a c), (> a d) at the same time? I want to get the largest (and the smallest)number without having to write nested ifs.
Can you use the max and min procedures? if the answer is yes, it's pretty simple:
(- (max a b c d) (min a b c d))
If not, remember that <, >, <=, >= accept a variable number of arguments, so this is valid code and will tell you if a is smaller than b and b is smaller than c and c is smaller than d (although you'll have to test more combinations of b, c, d to make sure that a is the smallest value).
(< a b c d)
Also remember to consider the cases when two or more numbers are equal (that's why it's a good idea to use <= instead of <).
Anyway, you'll have to use conditionals. Maybe nested ifs, or perhaps a cond to make things simpler - you can work out the details yourself, I'm guessing this is homework.
If you want to find the smallest and largest members of the list and you are not allowed to use the standard min and max library functions, then I can think of three approaches
Write your own min and max functions (hint: recursion). Apply both to the list to find your two values. Perform the subtraction.
Write a combined function (again, recursive) which will pass through the list once, returning another two-member list which contains the max and min. If the first element in the returned list is the max, then (apply - (find-min-and-max 3 2 8 7)), where find-min-and-max is your function, would return the result of the subtraction.
Use map.
Option 1 is less efficient than option 2 but much simpler to write. Option 3 is more complex than either but actually does what you asked (that is, compare a to b, c and d "at the same time").
For example, if I defined the following function:
(define (compare test x l)
(map (lambda (y) (test x y)) l))
then
(compare < 3 '(1 2 4))
would return (#f #f #t)
How is this useful to you? Well, if (compare < x l) returns all true, then x is smaller than all elements of l. If it returns all false, then x is bigger than all elements of l. So you could use map to build the code you want, but I think it would be ugly and not the most efficient way to do it. It does do what you specifically asked for, though (multiple simultaneous comparisons of list elements).

Resources