Многие проблемы в вашем коде:
- Глобально
setq
неопределенная переменная
(let (key))
не в одиночку делает ничего. Если вы хотите определить глобальную переменную, используйте defparameter
или defvar
.
- У вас
if
есть только тест, и никаких ветвей нет. Специальный оператор if
принимает условие, а затем выражение и необязательное выражение еще: (если тест, то [еще])
- Если вы хотели, чтобы ваш
return
внутри if
, ваш линейный поиск остановится при первом сравнении, из-за (return NIL
). Действительно, то, что вы написали бы, будет эквивалентно (return (= (first a) key))
, и loop
даже не понадобится в этом случае. Возможно, вы намеревались использовать return
для возврата значения из if
, но if
- это выражение, которое уже оценивается как значение. return
выходит из цикла (есть неявный (block NIL ...)
вокруг loop
).
(setq a (rest a))
это как (pop a)
и действительно будет правильным, если вы еще не вернулись с loop
на этом этапе.
- Для удобства, имейте в виду, что
=
предназначено для сравнения номера.
Начало кода можно записать в виде:
(let ((a '(8 6 2 3 9 5 1))
(key (read)))
(linear-search key a)
Тогда, как вы выполняете linear-search
зависит от того, что вы хотите узнать. Для этого есть встроенные (find
, member
). Вы также можете использовать some
с предикатом. Loop
имеет пункт thereis
. Вы даже можете попробовать с reduce
или map
с return-from
. Если вы хотите узнать do
или tagbody
, у вас будет возможность использовать (pop a)
.