Обратите внимание, что, хотя существующий ответ правильный, отключение предупреждений не является хорошей практикой. В вашем случае это, вероятно, не нужно.
Common Lisp имеет понятие единицы компиляции, где несколько определений группируются вместе. Это дает возможность компилятору / интерпретатору позаботиться о перекрестных ссылках между функциями (например, интерпретатор может собирать предупреждения и сохранять только те, которые не найдены позже).
Например, в файле #P"/tmp/foo.pl"
:
(defun mut-rec-foo (x)
(when (plusp x)
(mut-rec-bar (1- x))))
(defun mut-rec-bar (x)
(print x)
(mut-rec-foo (1- x)))
Не оценивать ничего в файле; вместо этого:
(compile-file #P"/tmp/foo.pl")
; compiling (DEFUN MUT-REC-FOO ...)
; compiling (DEFUN MUT-REC-BAR ...)
; /tmp/foo.fasl written
; compilation finished in 0:00:00.002
Без предупреждения. Затем вы можете позвонить (load #P"/tmp/foo.fasl")
, чтобы получить определения в вашей текущей среде lisp без предупреждений.
Обычно ASDF и расширение Quicklisp используют COMPILE-FILE
, поэтому ваша проблема должна исчезнуть, как только вы объедините свои файлы в систему.
Вы также можете сделать:
(with-compilation-unit ()
(defun mut-rec-foo/bis (x)
(when (plusp x)
(mut-rec-bar/bis (1- x))))
(defun mut-rec-bar/bis (x)
(print x)
(mut-rec-foo/bis (1- x))))
Оценка всего блока не показывает предупреждения для *EVALUATOR-MODE*
, являющегося одновременно :COMPILE
или :INTERPRET
.
То, что вы засвидетельствовали, происходит, когда вы оцениваете каждое выражение одно за другим (или, может быть, один регион за другим). Там компилятор не может знать, что функция уже существует. Отключение предупреждения - худший вариант, потому что вы могли действительно сделать ошибку.
Если вы заранее знаете, что функция будет существовать, но не в вашем модуле компиляции (может быть, она определена только во время выполнения), вы можете объявить этот факт как следующим образом:
(declaim (ftype function my-function))
Выше сказано, что my-function
должно быть принято fbound
для объекта типа function
. Вы также можете предоставить больше информации, уточнив, какую функцию вы заявляете:
(declaim (ftype (function (number) (values string &optional)) num-to-string))
... для функции, которая принимает число и возвращает ровно одно значение - строку.
(declaim (ftype (function () nil) forever-loop))
... для функции, которая ничего не принимает и никогда не возвращает значение (цикл или сигнализирует об ошибке).