Emacs 函数不工作时的Elisp

Emacs 函数不工作时的Elisp,emacs,elisp,Emacs,Elisp,我试图在一个骨架函数中编写一个循环。它应该很简单,但不起作用,这表明我不理解ELISP。我有以下资料: (define-skeleton test "" "" '(setq i 1) (while (< i 5) '(setq i (+ i 1))) ) (定义骨架测试 "" "" "(setq i 1) (而(

我试图在一个骨架函数中编写一个循环。它应该很简单,但不起作用,这表明我不理解ELISP。我有以下资料:

(define-skeleton test
  ""
  ""
  '(setq i 1)
  (while (< i 5)
  '(setq i (+ i 1)))
  )
(定义骨架测试
""
""
"(setq i 1)
(而(

当我计算这个时,我得到一个无限循环。发生了什么事?

删除将表单视为数据的引号。您还应该
绑定您的局部变量
i
,否则它将绑定一个全局变量。您需要进行如下评估:

(define-skeleton test
  "A test skeleton."
  (let ((i 1))
    (while (< i 5)
      (setq i (1+ i)))))                ; (incf i) would also work
(定义骨架测试
“测试骨架。”
(让((i)1))
(而(
更详细一点:
(setq i(1+i))
是一个列表(以及
(1+i)
),但读者知道当列表中的第一项是函数调用、宏或特殊表单(如
if
)时,应将其视为一个要计算的表单。当您引用列表时(通过在
'
前面加上前缀或将其包装成
(quote…
),它会告诉读者将整个列表视为数据,并返回未计算的列表


因此,
(setq i(1+i))
i
绑定到1的值加上先前的
i
值,
(setq i'(1+i))
i
绑定到未评估的列表
(1+i)
,而
(setq i(1+i))
只是将自身作为未评估的列表返回。

问题是,在骨架中“quote”是特殊的,但仅在“顶层”。即,您需要将您的
(while(
更改为
(while(

完美的答案,谢谢!出于某种原因,我觉得我需要引号来阻止setq提供不必要的输出。您可以使用
dotimes
函数:
(dotimes(i5)(dostuff))