让我们写下如果 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))
Well ARRNUM
is the symbol MY-ARRAY
so this prints NIL
,尽管可能不是您期望的流。
(print arrnum)
这打印MY-ARRAY
。
(setf (aref arrnum 3) 5)
WellARRNUM
不是数组,所以这里有错误。
所以我们未能评估这个表达式,因为扩展宏失败了。
以下是您可以做的其他一些事情:
(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)