В этом примере кода
(defvar mat (make-array (list 5 3)
:initial-contents '((1 2 3)
(4 5 6)
(7 8 9)
(10 11 12)
(13 14 15))))
(defun mk-idx (dims dim)
(loop
for i below (length dims)
if (= i dim) collect 1
else collect 0))
(defun loop-over-dim (ary dim)
(macrolet ((expan (a d)
(let* ((dims (array-dimensions a))
(dim-max (nth d dims))
(sel (mk-idx dims d))
(i (gensym)))
`(loop
for ,i below ,dim-max
collect (aref ,a ,@(substitute i 1 sel))))))
(expan ary dim)))
Я пытаюсь получить доступ к матрице с одним фиксированным размером (в настоящее время с координатой 0
).Итак (loop-over-dim mat 0) ;; => (1 4 7 10 13)
;по крайней мере, это и есть намерение.
Однако при попытке его скомпилировать SBCL сообщает мне, что
Значение ARY не имеет типа ARRAY
.style-warning над ошибкой говорит о том, что аргументы loop-over-dim
не используются.Но они используются в привязках macrolet
.
Итак, кроме стилистических соображений, почему я получаю ошибку, что ARY
не является массивом?
Я уже пытался переместить let*
за пределы macrolet
, но с теми же результатами (ошибка).
Я также пытался обернуть loop-over-dim
внутри eval-when
, но без кубиков.
Может быть, macrolet
(или макросы в целом) являются (являются) инструмент (ы) для этой работы?(см. Hyperspec ,
[...], но последствия не определены, если определения локальных макросов ссылаются на любые привязки локальной переменной или функции, видимые в этой лексической среде.
)