BigBro666
BigBro666

Reputation: 81

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

Upvotes: 1

Views: 2877

Answers (1)

Renzo
Renzo

Reputation: 27434

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

Upvotes: 2

Related Questions