2
votes

So I've gotten rather simple task, in theory.

"Create a procedure where you take an integer as a parameter. If the integer is 0, return 0. If the integer is less than 0, return -1. If the integer is more than 0, return 1.

Solve this task without using if/cond(the only special forms allowed, are define, and, or)."

A very unpractical task, but a requirement for my course nonetheless. I've been stuck with this task for hours now, so I'd love some input!

Keep in mind that the procedure must return -1, 0 or 1. #t or #f are not good enough.

2

2 Answers

6
votes

Both and and or are special versions of if. Eg.

(and a b)           ; is the same as
(if a b #f)

(and a b c ...)         ; is the same as
(if a (and b c ...) #f)

(or a b)    ; is the same as
(if a
    a       ; though a is only evaluated once!
    b)

(or a b c ...)  ; is the same as
(if a
    a           ; though a is only evaluated once!
    (or b c ...))

Notice that for 3 or more elements the result has and or or in it. You just apply the same transformation until you have something with just if.

If you want something like:

(if a 'x 'y)

You see that its obviously (or (and a 'x) 'y) since it turns into

(if (if a 'x #f)
    (if a 'x #f)
    'y)

Know that every value except #f is considered a true value. The basic method of doing this in "reverse" is knowing how and and or short circuits like if. If you need a special value returned instead of the result of a predicate you use and:

(and (null? x) 'empty-result)

If you need a false value to continue logic you use or

(or (and (null? x) 'empty-result)
    (and (pair? x) 'pair-result))

If you need a default and have a or you just add it.

(or (and (null? x) 'empty-result)
    (and (pair? x) 'pair-result)
    'default-result)

If you happen to have and in the outer you need to wrap an or to get the default-result:

(or (and ...)
    'default-result)

Good luck!

2
votes

Here's a pretty simple implementation:

(define (signum n)
  (or (and (zero? n) 0)
      (and (positive? n) 1)
      (and (negative? n) -1)))

Edit: I wrote my answer before I read Sylwester's post, but you should definitely read it for the theory of how this construction works.