Почему ваш код не работает
Может кто-нибудь показать мне, где я ошибся с моей частью кода?
(defun( MIN-2 a b)
(cond
((and (numberp a) (numberp b) (<= a b)) a b)
((and (numberp a) (numberp b) nil) ERROR)
)
)
Позвольте мне переформатировать ваш код (авто-отступ+ сжать скобки):
(defun (MIN-2 a b) ;; << bad syntax, as already pointed out in another answer
(cond
((and (numberp a) (numberp b) (<= a b))
a
b)
((and (numberp a) (numberp b) nil)
ERROR)))
Исправим синтаксис defun
:
(defun MIN-2 (a b)
(cond
((and (numberp a) (numberp b) (<= a b))
a
b)
((and (numberp a) (numberp b) nil)
ERROR)))
Ошибка (я компилирую код в Emacs + SBCL):
Неопределенная переменная: ERROR
Действительно, error
здесь свободная переменная.Вы должны указать это.
(defun MIN-2 (a b)
(cond
((and (numberp a) (numberp b) (<= a b))
a
b)
((and (numberp a) (numberp b))
'ERROR)))
Предупреждение:
Удаление недоступного кода (ОШИБКА подчеркнута) .
Действительно, условие здесь является выражением and
, где хотя бы одно выражение является NIL
, что означает, что конъюнкция всегда ложна.Случай не может произойти, поэтому он был оптимизирован.
Кроме того, тест первого предложения:
(and (numberp a) (numberp b) (<= a b))
И тело предложения a
, за которым следует b
, что означает, что a
оценивается, его значение отбрасывается (оно никогда не используется), затем b
оценивается, и его значение является значением выражения cond
: вы всегда возвращаете b
, когда оба входа являются числами, такимичто a <= b
.
Очевидно, это не то, что вы должны делать.Другие ответы уже охватывали хорошие решения.
Альтернативы
Я также здесь, чтобы предложить альтернативные, не обязательно домашние ответы:
Исключения для вылова
(defun min-2 (a b)
(handler-case (if (<= a b) a b)
(error () 'error)))
Исключения для вылова (бис)
(defun min-2 (a b)
(or (ignore-errors (if (<= a b) a b))
'error))
Использование общих функций
(defgeneric min-2 (a b)
(:method ((a number) (b number)) (if (<= a b) a b))
(:method (a b) 'error))