Документация по минибуферу SLIME и CCL в Emacs
При использовании Emacs, SLIME и Clozure CL у меня есть небольшой недостаток: подпись функции для aref
(Я еще не видел других экземпляров) отображается только как (aref a)
,
Когда я иду к исходному коду, рассматриваемый код начинается с (defun aref (a &lexpr subs)
, Насколько я знаю, &lexpr
не является допустимым ключевым словом лямбда-списка CL. Таким образом, это означает, что SLIME не показывает правильную сигнатуру функции из-за странного ключевого слова.
Но когда я делаю то же самое для svref
Скажем, нет ничего (по крайней мере, мне), подтверждающего приведенную выше гипотезу. Так что, может быть, SLIME тоже что-то делает.
Кто-нибудь может указать на соответствующую документацию (я не нашел ничего релевантного в руководстве SLIME и в руководстве CCL), или у кого-нибудь есть обходной путь / решение?
1 ответ
SVREF
не принимает список индексов массива, так как его первый аргумент является вектором. Массив может быть многомерным, что объясняет, почему существует различное число индексов. За AREF
Возможные источники:
.../ccl/level-0/l0-array.lisp
#'AREF
.../ccl/compiler/optimizers.lisp
(COMPILER-MACRO AREF)
.../ccl/compiler/nx1.lisp
#'CCL::NX1-AREF
Из них только первый имеет редкость &lexpr
Ключевое слово в списке аргументов.
Эксперимент:
CL-USER> (defun foobar (a &lexpr b) (list a b))
;Compiler warnings :
; In FOOBAR: Unused lexical variable &LEXPR
FOOBAR
Давайте используем неэкспортированный символ из CCL (автозаполнение нашло его):
CL-USER> (defun foobar (a ccl::&lexpr b) (list a b))
FOOBAR
На этот раз это работает, давайте попробуем это:
CL-USER> (foobar 0 1 2 3 4)
(0 17563471524599)
Эволюция Лисп говорит (выделение мое):
MacLisp представил LEXPR, который представляет собой тип функции, которая принимает любое количество аргументов и помещает их в стек;
(см. https://www.dreamsongs.com/Files/Hopl2.pdf).
Исправить заменой
Вы можете исправить это на уровне Swank, заменив &lexpr
от &rest
, Вам нужно только патч ccl.lisp
, который обеспечивает реализацию для arglist
для Clozure:
(defimplementation arglist (fname)
(multiple-value-bind (arglist binding) (let ((*break-on-signals* nil))
(ccl:arglist fname))
(if binding
(substitute '&rest 'ccl::&lexpr arglist)
:not-available)))
Подробнее
На самом деле, в swank-arglists.lisp
Вы можете видеть, что материал, который неизвестен, помещен в отдельный список, называемый :unknown-junk
, Чтобы увидеть это в действии, сделайте:
CL-USER> (trace swank::decoded-arglist-to-string)
NIL
Затем написать (aref
и нажмите пробел, который запускает запрос для списка аргументов и производит следующую трассировку:
0> Calling (SWANK::DECODED-ARGLIST-TO-STRING #S(SWANK/BACKEND:ARGLIST :PROVIDED-ARGS NIL :REQUIRED-ARGS (CCL::A) :OPTIONAL-ARGS NIL :KEY-P NIL :KEYWORD-ARGS NIL :REST NIL :BODY-P NIL :ALLOW-OTHER-KEYS-P NIL :AUX-ARGS NIL :ANY-P NIL :ANY-ARGS NIL :KNOWN-JUNK NIL :UNKNOWN-JUNK (CCL::&LEXPR CCL::SUBS)) :PRINT-RIGHT-MARGIN 159 :OPERATOR AREF :HIGHLIGHT (0))
<0 SWANK::DECODED-ARGLIST-TO-STRING returned "(aref ===> a <===)"
Обратите внимание на :UNKNOWN-JUNK (CCL::&LEXPR CCL::SUBS))
часть. Может быть, лучше исправить это, чтобы Свонк узнал о &lexpr
?