Давайте запишем, что произошло бы, если бы lisp оценивал ваш файл построчно:
(setf my-array (make-array 4 :initial-element 3))
На данный момент MY-ARRAY
привязано к #(3 3 3 3)
(print my-array)
Печать #(3 3 3 3)
(setf (aref my-array 2) 5)
(print my-array)
Изменение элемента и печать #(3 3 5 3)
(defmacro set3To5 (arrnum)
(print (arrayp arrnum))
(print arrnum)
(setf (aref arrnum 3) 5))
Теперь макрос SET3TO5
определен.
(set3To5 my-array)
Первый шаг здесь (о котором мы не упоминали ранее, хотя это и происходило) - это макроразложение.Компилятор знает, что SET3TO5
является макросом, поэтому он вызывает функцию макроса с MY-ARRAY
(символом) в качестве аргументов.Давайте посмотрим, что происходит внутри этого макроса:
(print (arrayp arrnum))
Ну ARRNUM
- это символ MY-ARRAY
, поэтому он печатает NIL
, хотя, возможно, и не тот поток, который вы ожидаете.
(print arrnum)
Это печатает MY-ARRAY
.
(setf (aref arrnum 3) 5)
Ну ARRNUM
не является массивом, поэтому у вас есть ошибка здесь.
Таким образом, мы не смогли оценить это выражение из-за расширениямакрос не удался.
Вот еще несколько вещей, которые вы могли бы сделать:
(defun set1 (arrnum)
(print (arrayp arrnum))
(print arrnum)
(setf (aref arrnum 3) 5))
(defun set2 (arrnum)
(list 'setf (list 'aref arrnum 3) 5))
(defmacro set3 (arrnum)
(list 'setf (list 'aref arrnum 3) 5))
А теперь оцените:
CL-USER> (set1 my-array)
T
#(3 3 5 3)
5
CL-USER> my-array
#(3 3 5 5)
CL-USER> (set2 my-array)
(SETF (AREF #(3 3 5 5) 3) 5)
CL-USER> (set2 'foo)
(SETF (AREF FOO 3) 5)
CL-USER> (setf (aref my-array 3) 1)
1
CL-USER> (set3 my-array)
5
CL-USER> my-array
#(3 3 5 5)