views:

100

answers:

2

This function is a CLisp function, this is part of a homework problem, but which is supposed to be written in this different format (the second function).

(defun range (m M) (cond
((> m M) '() )
((= m M) '() )
((< m M) (cons m (range (+ m 1) M ) ) )  
)
)


(define (range m M) (cond
    ((> m M) '() )
    ((= m M) '() )
    ((< m M) (cons m (range (+ m 1) M ) ) )
)
)

These should both take a min value (m) and a max value (M) and return the list of integers from min to max (exluding the max value / M-1)

I have traced this over and over and I can't see why it is just returning NIL it must be a very dumb logic mistake.

(range 1 4)  => result (1 2 3)

m=1 | M=4 ==> return (cons 1 (2 3) )
m=2 | M=4 ==> return (cons 2 (3) )
m=3 | M=4 ==> return (cons 3 () )
m=4 | M=4 ==> return ()
    v         ^
    ---------/

I'm going crazy trying to figure out WHY this is not performing like I trace it.

Again, when I execute the function it results in NIL.

+5  A: 

I ran this using SBCL and it complained that the variable M appears twice in the parameter list. Lisp is not case-sensitive for variable names.

On changing it to

(defun range (m MM) 
  (cond
      ((> m MM) '() )
      ((= m MM) '() )
      ((< m MM) (cons m (range (+ m 1) MM)))))

It worked fine.

> (trace range)
> (range 1 4)
  0: (RANGE 1 4)
    1: (RANGE 2 4)
      2: (RANGE 3 4)
        3: (RANGE 4 4)
        3: RANGE returned NIL
      2: RANGE returned (3)
    1: RANGE returned (2 3)
  0: RANGE returned (1 2 3)
-> (1 2 3)

I checked with CLISP. With different variable names it works OK. CLISP does not pick up the error, unlike SBCL.

<[1]> (defun range (m MM) (cond ((>= m MM) '())((< m MM) (cons m (range (+ m 1) MM )))))
RANGE

[2]> (range 1 4)
(1 2 3)

Here is your version:

[3]> (defun range (m M) (cond ((>= m M) '())((< m M) (cons m (range (+ m 1) M)))))

RANGE

[4]> (range 1 4)
Nil
Tim Josling
Yes I checked with CLISP. With different variable names it works OK. CLISP does not pick up the error, unlike SBCL. <b>[1]> (defun range (m MM) (cond((>= m MM) '() )((< m MM) (cons m (range (+ m 1) MM ) ) ) ))RANGE[2]> (range 1 4)(1 2 3)Here is your version:[3]> (defun range (m M) (cond((>= m M) '() )((< m M) (cons m (range (+ m 1) M ) ) ) ))RANGE[4]> (range 1 4)Nil
Tim Josling
@Tim Josling: this is the right answer I think. Can you fix the formatting so that it's easier to read? Help is here http://stackoverflow.com/editing-help
spong
I think the major lesson (even more important than learning that some languages are case-insensitive) is to use proper names! What does 'm' mean to the reader of the code? Nothing. Use proper names and tell your teacher to mark anybody down for not using proper names in their homework.
HD
A: 

Thank you so much!

Yeah, it didn't complain at all about that; I guess that is what I get for not knowing the language enough. Your help is greatly appreciated.

=]

aitee