N.A.
N.A.

Reputation: 103

Writing procedure with "and" and "or" in Scheme

I am learning Scheme with DrRacket and working on a procedure with name 'sign' that takes an argument and returns -1 if it's less than 0, 1 if it's greater than 0, and 0 if = 0.

My code is the following

(define (sign x)
     (and (> x 0) 1)
      (and (= x 0) 0)
       (and (< x 0) -1))

I can only use 'and' and 'or' to write the code in my task, meaning I can't use 'if' and 'cond' etc.

My code returns #t, when running it with (sign 5) or anything else.

Upvotes: 0

Views: 151

Answers (2)

Sylwester
Sylwester

Reputation: 48775

My code returns #t, when runnig it with (sign 5) or anything else.

This is not true. It will return -1 when argument is negative and #f otherwise.

Imagine calling (sign 1), that will:

  • (and (> 1 0) 1) gets evaluated to #t, but its value is not returned or saved anywhere and is dead code
  • (and (= 1 0) 0) gets evaluated to #f, but its value is not returned or saved anywhere and is dead code
  • (and (< x 0) -1) get evaluated to #f. Since this is in the tail position this value is returned and is the result of the procedure.

This procedure however:

(define (add a b)
  (display "adding "
  (display a)
  (display " and "
  (display b)
  (newline)
  (+ a b))

This one has 6 expressions and all of them are doing something usefull, because the first 5 has side effects that prints "adding <a> and <b>\n", while the returned value from them are disregarded the last expressions return is the result of the procedure. The last expression is called the tail expression.

When creating procedures you should not have more than one expression that does the work unless the design is using side effects. eg. your 3 and cannot be separate. You need logic that combines them. Since the false values are #f, but the results of each is a number and always considered true, you can have these 3 in an or:

(define (my-sign x)
  (or (and (> x 0) 1)
      (and (= x 0) 0)
      (and (< x 0) -1)))

When calling (my-sign 1) (> x 0) will be #t where 1 gets evaluated and the result of the first and expression and since or will stop at the first true value the result becomes 1. Also note that the last expression is not needed as we know that if it isn't above or equal to zero it has to be below zero. Thus the last and expression can be replaced by -1:

(define (my-sign x)
  (or (and (> x 0) 1)
      (and (= x 0) 0)
      -1)) ; if not equal or higher than 0 it has to be negative!

Upvotes: 2

&#211;scar L&#243;pez
&#211;scar L&#243;pez

Reputation: 236150

First of all, the sign procedure already exists and you're overwriting it, something to be aware of.

So you have this requirement of only using and, or in your implementation. Well, you're just missing the or part :)

(define (sign x)
  (or
   (and (> x 0) 1)
   (and (= x 0) 0)
   (and (< x 0) -1)))

For example:

(sign -10) ; -1
(sign 100) ;  1
(sign 0)   ;  0

Upvotes: 2

Related Questions