Проверка кода
Указанный код плохо отформатирован. Очень важно часто проверять ваш код, чтобы убедиться, что по крайней мере синтаксис правильный. Вместо того, чтобы писать код изолированно, вы должны попросить среду, интерпретатор, проанализировать ваш код и выполнить его. У вас будет более короткая обратная связь l oop, что поможет правильно понять код.
Например, если вы начинаете переводчика (вы упомянули clisp
), вы находитесь в режиме чтения Eval Print L oop (REPL), где вы пишете формы Lisp, которые оцениваются для получения результата, который печатается. Поэтому, просто написав код, он будет проанализирован и оценен, что может быстро сообщить вам о возможных ошибках.
Так что, если вы напишите код так, как вы его написали, вы заметите, что интерпретатор сначала читает это:
(defun (find-min a b))
Это потому, что все скобки сбалансированы: Читатель Lisp (R в REPL) создаст список из двух элементов, а именно defun
и список (find-min a b)
. Когда оценка выполнена (E в REPL), список будет интерпретирован как форма Lisp, но это неверно сформированный defun
.
DEFUN
ожидает имя функции, сопровождается списком привязок переменных, за которым следует тело функции. Так что вы можете попробовать написать, например:
(defun find-min (a b)
0)
Это выше определяет функцию с именем find-min
, которая принимает два параметра a
и b
и всегда оценивается как 0 (тело функции ).
В вашем случае вы хотите написать:
(defun find-min (a b)
(cond ...))
Вы COND
форма также искажена:
(cond
(> a b) (find-min b (read))
(< a b) (find-min a (read))
)
Каждый предложение в cond
должно быть списком , содержащим сначала тест, а затем ноль или более выражений. Таким образом, это будет:
(cond
((> a b) ...)
((< a b) ...))
Обратите внимание, что есть оставшийся случай, а именно (= a b)
, который не рассматривается.
Подход
Но в целом, я делаю не понимаю, что ваш код пытается достичь. Поскольку все входные данные должны быть получены с (read)
, нет необходимости принимать аргументы a
и b
. Все это может быть все oop:
(defun read-min ()
(loop
for val = (read)
for zerop = (= val zero)
for min = val then (if zerop min (min min val))
until (= val 0)
finally (return min)))
Как предполагает @leetwinski, есть и более короткая альтернатива:
(loop for val = (read) until (= val 0) minimizing val)
Но я полагаю, вы не собираетесь использовать форма l oop, поэтому вы должны попытаться написать рекурсивную функцию, которая делает то же самое.
Что вам нужно сделать, это передать текущее минимальное значение, когда-либо прочитанное вашей функции, рекурсивно, например, так:
(defun read-min-rec (min-so-far)
...)