Common lisp lisp非法函数调用
我刚刚开始学习Common Lisp,我尝试了第一个Project Euler问题(将x以下可被3或5整除的所有数字相加)。我试图定义一个宏来将这个过程推广到可被给定因子列表整除的数字,但遇到了麻烦:当我运行宏时,它说有一个非法函数调用Common lisp lisp非法函数调用,common-lisp,sbcl,Common Lisp,Sbcl,我刚刚开始学习Common Lisp,我尝试了第一个Project Euler问题(将x以下可被3或5整除的所有数字相加)。我试图定义一个宏来将这个过程推广到可被给定因子列表整除的数字,但遇到了麻烦:当我运行宏时,它说有一个非法函数调用setf,并警告说sum未定义。其他人以前也发过这个问题,但括号有问题,但我举了一个例子,说明我希望宏能扩展成什么,这个函数工作正常,括号完全在同一个位置。下面是示例函数(工作正常)和宏(抛出错误)的代码: 我正在使用SBCL和lispstick。谢谢 如果我将小
setf
,并警告说sum
未定义。其他人以前也发过这个问题,但括号有问题,但我举了一个例子,说明我希望宏能扩展成什么,这个函数工作正常,括号完全在同一个位置。下面是示例函数(工作正常)和宏(抛出错误)的代码:
我正在使用SBCL和lispstick。谢谢 如果我将小点移动一点,这对我很有用:
(defmacro count-arbitrary (limit &rest divisors)
`(let ((sum 0))
(dotimes (n (1+ ,limit) sum)
(dolist (each ',divisors)
(when (= 0 (mod n each))
(setf sum (+ n sum))
(return))))))
如果我将小点移动一点,这对我来说很有用:
(defmacro count-arbitrary (limit &rest divisors)
`(let ((sum 0))
(dotimes (n (1+ ,limit) sum)
(dolist (each ',divisors)
(when (= 0 (mod n each))
(setf sum (+ n sum))
(return))))))
让我们看一下扩展:
CL-USER 29 > (pprint (macroexpand-1 '(count-arbitrary 30 3 5)))
(DOTIMES (N (1+ 30) 0)
(DOLIST (EACH (3 5))
(WHEN (= 0 (MOD N EACH))
(SETF SUM (+ N 0)) (RETURN))))
您可以看到sum
变量的LET
丢失,(35)
缺少引号(因此是非法函数调用),并且sum
前面的逗号都是错误的
通常,宏没有什么意义,因为可以将数字作为函数的附加参数提供:
(defun count-multiples-example (limit divisors &aux (sum 0))
(dotimes (n (1+ limit) sum)
(dolist (each divisors)
(when (= 0 (mod n each))
(incf sum n)
(return)))))
或者这个:
CL-USER 35 > (defun count-multiples-example (limit &rest divisors &aux (sum 0))
(dotimes (n (1+ limit) sum)
(dolist (each divisors)
(when (zerop (mod n each))
(incf sum n)
(return)))))
COUNT-MULTIPLES-EXAMPLE
CL-USER 36 > (count-multiples-example 30 3 5)
225
让我们看一下扩展:
CL-USER 29 > (pprint (macroexpand-1 '(count-arbitrary 30 3 5)))
(DOTIMES (N (1+ 30) 0)
(DOLIST (EACH (3 5))
(WHEN (= 0 (MOD N EACH))
(SETF SUM (+ N 0)) (RETURN))))
您可以看到sum
变量的LET
丢失,(35)
缺少引号(因此是非法函数调用),并且sum
前面的逗号都是错误的
通常,宏没有什么意义,因为可以将数字作为函数的附加参数提供:
(defun count-multiples-example (limit divisors &aux (sum 0))
(dotimes (n (1+ limit) sum)
(dolist (each divisors)
(when (= 0 (mod n each))
(incf sum n)
(return)))))
或者这个:
CL-USER 35 > (defun count-multiples-example (limit &rest divisors &aux (sum 0))
(dotimes (n (1+ limit) sum)
(dolist (each divisors)
(when (zerop (mod n each))
(incf sum n)
(return)))))
COUNT-MULTIPLES-EXAMPLE
CL-USER 36 > (count-multiples-example 30 3 5)
225