If else clause or cond in Racket
Asked Answered
T

3

7

I am trying to write a simple program in Racket that prints 1 if the value of a is > 1, prints 0 if the value of a = 0 and -1 if a < 0 . I wrote the following but looks like it is not taking care of the third condition. Actually, I have not included the third condition so I don't know how to check for all three conditions using 'if' clause. A little guidance is appreciated.

I am new to Racket. My program is:

#lang racket
(define a 3);


(if (> a 0)
    0 
    1)
-1

Thanks in advance.

Teahan answered 4/5, 2015 at 23:22 Comment(0)
M
12

The function you are looking for is already defined under the name sgn.

The reason your implementation doesn't work is that it is incomplete. You want:

(if (= a 0)
    0
    (if (< a 0)
        -1
        1))

Or just the better looking:

(cond 
    [(negative? n) -1]
    [(positive? n)  1]
    [else 0])
Mia answered 4/5, 2015 at 23:28 Comment(1)
One small note since the question was tagged just racket (not also scheme): Although not mandatory it's idiomatic in Racket to use square brackets for certain forms like the clauses in cond. For example (cond [cond expr] [else expr]).Oran
I
3

So how you describe it you have two consequences and one alternative. I would then have used cond:

(cond ((> a 0) 1)
      ((= a 0) 0)
      (else -1))  ; if it's not greater or equal it has to be less than

With cond each term you can expect all previous to be false, thus the last test is not needed since if it's not greater or equal it has to be less than 0. This is exactly the same as writing:

(if (> a 0)
    1
    (if (= a 0) 
        0
        -1))

The main difference is that it looks slightly better with cond. If you have a need for begin (side effects) then using cond would also be beneficial since it has implicit begin:

(define seen
  (let ((hash (make-hash)))
    (lambda (x) 
      (cond ((hash-ref hash x #f) #t)
            (else (hash-set! hash x #t) #f)))))

The same with if:

(define seen
  (let ((hash (make-hash)))
    (lambda (x) 
      (if (hash-ref hash x #f) 
          #t
          (begin
            (hash-set! hash x #t)
            #f)))))

Its the same but I feel cond wins since it's less indentation and more flat.

Inculcate answered 4/5, 2015 at 23:28 Comment(2)
And that is why SO should have a "I'm answering this" flag. By the way, you need to fix your last example!Mia
@Viclib Yes indeed. fixedInculcate
R
0

I'm a beginner CS student, but we started with Racket and this is how we would make this. Also, I'm just going by exactly what you say in your question "prints 1 if the value of a is > 1, prints 0 if the value of a = 0 and -1 if a < 0"

(cond
[(> a 1) 1]
[(= a 0) 0]
[(< a 0) -1])

Something else that I might add just purely as a CS student going by class standards, when we were writing functions that used intervals we always wrote an appropriate amount of check-expects to see if anything unexpected happens. I noticed that you have something happen when a > 1, a = 0, and everything below 0 would be = -1. So if you wrote a = 1 it would return with -1 if you had put "else" for anything that wasn't >1, = 0, or <0 . I don't know what you would want to happen if a = 1, but I thought I would just throw that out for good measure.

If you were to put in a = 1 with the cond written above it would just return with "cond: all question results were false".. Oki, now I'm done.

Relaxation answered 21/10, 2020 at 6:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.