Документация по минибуферу SLIME и CCL в Emacs - PullRequest
0 голосов
/ 15 декабря 2018

При использовании Emacs, SLIME и Clozure CL у меня есть небольшое замечание: подпись функции для aref (я еще не видел других экземпляров) отображается только как (aref a).

Когда яперейти к исходному коду, о котором идет речь, начинается с (defun aref (a &lexpr subs).Насколько я знаю, &lexpr не является допустимым ключевым словом лямбда-списка CL.Таким образом, это означает, что SLIME не показывает правильную сигнатуру функции из-за ключевого слова "странный".

Но когда я делаю то же самое для svref, скажем, нет ничего (по крайней мере, мне), что подтверждаетвышеуказанная гипотеза.Так что, возможно, SLIME тоже что-то делает.

Может кто-нибудь указать на соответствующую документацию (я не нашел ничего релевантного в руководстве SLIME и в руководстве CCL), или у кого-нибудь есть обходной путь / решение?

1 Ответ

0 голосов
/ 21 декабря 2018

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)

Эволюция Lisp говорит (выделено мое):

MacLisp представил LEXPR, который является типом функции, которая принимает любое количество аргументов и помещает их в стек ;

(см. https://www.dreamsongs.com/Files/Hopl2.pdf)

Исправить заменой

Вы можете исправить это на уровне Суонка, заменив &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 и нажмите Space , который запускает запрос для списка аргументов и производит следующую трассировку:

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?

...