Что не так с этой функцией Lisp? - PullRequest
1 голос
/ 12 октября 2010

Эта функция является функцией CLisp, это часть проблемы с домашним заданием, но она должна быть написана в другом формате (вторая функция).

(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 ) ) )
)
)

Они должны принимать минимальное значение (m) и максимальное значение (M) и возвращать список целых чисел от минимального до максимального (исключая максимальное значение / M-1)

Я прослеживал это снова и снова, и я не понимаю, почему он просто возвращает NIL, это должно быть очень глупой логической ошибкой.

(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         ^
    ---------/

Я схожу с ума, пытаясь понять, ПОЧЕМУ это не работает так, как я прослеживаю.

Опять же, когда я выполняю функцию, это приводит к NIL.

1 Ответ

5 голосов
/ 12 октября 2010

Я запустил это с использованием SBCL, и он пожаловался, что переменная M дважды появляется в списке параметров. Лисп не учитывает регистр имен переменных.

При изменении на

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

Работало нормально.

> (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)

Я проверил с CLISP. С разными именами переменных все работает нормально. CLISP не принимает ошибку, в отличие от 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)

Вот ваша версия:

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

RANGE

[4]> (range 1 4)
Nil
...