Reputation: 103
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
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
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