LISP:函数位置的非法参数
LISP: Illegal argument in functor position
我的代码如下所示:
(defmacro createList (a b c)
(let ((lst (list a b c)))
(write lst)))
(createList 1 2 3 )
我得到:
Illegal argument in functor position: 1 in (1 2 3).
我知道这里有一个类似的问题:
Lisp Illegal argument in functor position
但是我无法调整我的问题的答案。括号问题在哪里?我做错了什么?
write
函数的结果是它的参数。因此,(write "Tom")
的结果是 "Tom"
(它写入输出流的事实是该函数的副作用)。
宏return要计算的形式,通常表示列表。
您的宏创建列表 (1 2 3)
,然后将其写出。 write
是在宏扩展时计算的,而不是 "runtime"。因为 write
returns 它的参数是它的 return 值,而 write
是最后调用的函数,宏函数的结果是 [=12= 的结果] 函数,或者,在本例中,(1 2 3)
.
然后计算 (1 2 3)
,但是如果您尝试在顶层键入 (1 2 3)
,它会将 1
视为表单的第一个参数,并尝试将其作为一个函数进行评估——它不是,它只是数字 1.
如果你想看看你的宏会展开什么,你可以试试:(macroexpand '(createlist 1 2 3))
你可以看到下面的结果:
[2]> (macroexpand '(createlist 1 2 3))
(1 2 3)
(1 2 3) ;
T
您看到第一个 (1 2 3)
,这是您 write
的结果。然后您会看到第二个 (1 2 3)
,它是宏展开的结果(上面讨论过),紧接着是 T
,它是 macroexpand
函数的结果。
这就是正在发生的事情。不清楚如何修复它,因为不清楚你想做什么。
也许这就是您想要做的:
(defmacro createlist (a b c)
`(list ,a ,b ,c))
[5]> (macroexpand `(createlist 1 2 3))
(LIST 1 2 3) ;
T
write
returns 作为第一个参数传递给它的对象。因此,您从宏中 returning lst
。无论你从宏中 return 都被认为是 lisp 代码。
当运行你的代码时,你应该看到
(1 2 3)
在错误之前的标准输出上。这就是你给 write
的结果: (list a b c)
与 a
绑定到 1
等的结果
lisp 代码中列表的第一个元素是被调用的函数。显然,作为此列表的第一个元素的 1
不是函数。
为了调试此类错误,使用 macroexpand
通常很有帮助:
(defmacro createList (a b c)
(let ((lst (list a b c)))
(write lst)))
(format t "~%Expanded ~a~%" (macroexpand-1 '(createList 1 2 3)))
我的代码如下所示:
(defmacro createList (a b c)
(let ((lst (list a b c)))
(write lst)))
(createList 1 2 3 )
我得到:
Illegal argument in functor position: 1 in (1 2 3).
我知道这里有一个类似的问题: Lisp Illegal argument in functor position
但是我无法调整我的问题的答案。括号问题在哪里?我做错了什么?
write
函数的结果是它的参数。因此,(write "Tom")
的结果是 "Tom"
(它写入输出流的事实是该函数的副作用)。
宏return要计算的形式,通常表示列表。
您的宏创建列表 (1 2 3)
,然后将其写出。 write
是在宏扩展时计算的,而不是 "runtime"。因为 write
returns 它的参数是它的 return 值,而 write
是最后调用的函数,宏函数的结果是 [=12= 的结果] 函数,或者,在本例中,(1 2 3)
.
(1 2 3)
,但是如果您尝试在顶层键入 (1 2 3)
,它会将 1
视为表单的第一个参数,并尝试将其作为一个函数进行评估——它不是,它只是数字 1.
如果你想看看你的宏会展开什么,你可以试试:(macroexpand '(createlist 1 2 3))
你可以看到下面的结果:
[2]> (macroexpand '(createlist 1 2 3))
(1 2 3)
(1 2 3) ;
T
您看到第一个 (1 2 3)
,这是您 write
的结果。然后您会看到第二个 (1 2 3)
,它是宏展开的结果(上面讨论过),紧接着是 T
,它是 macroexpand
函数的结果。
这就是正在发生的事情。不清楚如何修复它,因为不清楚你想做什么。
也许这就是您想要做的:
(defmacro createlist (a b c)
`(list ,a ,b ,c))
[5]> (macroexpand `(createlist 1 2 3))
(LIST 1 2 3) ;
T
write
returns 作为第一个参数传递给它的对象。因此,您从宏中 returning lst
。无论你从宏中 return 都被认为是 lisp 代码。
当运行你的代码时,你应该看到
(1 2 3)
在错误之前的标准输出上。这就是你给 write
的结果: (list a b c)
与 a
绑定到 1
等的结果
lisp 代码中列表的第一个元素是被调用的函数。显然,作为此列表的第一个元素的 1
不是函数。
为了调试此类错误,使用 macroexpand
通常很有帮助:
(defmacro createList (a b c)
(let ((lst (list a b c)))
(write lst)))
(format t "~%Expanded ~a~%" (macroexpand-1 '(createList 1 2 3)))