Common lisp lisp非法函数调用

Common lisp lisp非法函数调用,common-lisp,sbcl,Common Lisp,Sbcl,我刚刚开始学习Common Lisp,我尝试了第一个Project Euler问题(将x以下可被3或5整除的所有数字相加)。我试图定义一个宏来将这个过程推广到可被给定因子列表整除的数字,但遇到了麻烦:当我运行宏时,它说有一个非法函数调用setf,并警告说sum未定义。其他人以前也发过这个问题,但括号有问题,但我举了一个例子,说明我希望宏能扩展成什么,这个函数工作正常,括号完全在同一个位置。下面是示例函数(工作正常)和宏(抛出错误)的代码: 我正在使用SBCL和lispstick。谢谢 如果我将小

我刚刚开始学习Common Lisp,我尝试了第一个Project Euler问题(将x以下可被3或5整除的所有数字相加)。我试图定义一个宏来将这个过程推广到可被给定因子列表整除的数字,但遇到了麻烦:当我运行宏时,它说有一个非法函数调用
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