Создание файла lisp, который читает цифры с клавиатуры, пока не будет прочитано 0. Показать минимальное значение - PullRequest
1 голос
/ 30 апреля 2020

Я застрял, я сделал это таким образом, но я чувствую, что это неправильно.

(defun (find-min a b))
   (cond 
        (> a b) (find-min b (read))
        (< a b) (find-min a (read))
        )
   (display (find-min (read) (read)))

1 Ответ

3 голосов
/ 30 апреля 2020

Проверка кода

Указанный код плохо отформатирован. Очень важно часто проверять ваш код, чтобы убедиться, что по крайней мере синтаксис правильный. Вместо того, чтобы писать код изолированно, вы должны попросить среду, интерпретатор, проанализировать ваш код и выполнить его. У вас будет более короткая обратная связь 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)
  ...)
...