【发布时间】:2022-01-11 03:52:18
【问题描述】:
我想为iterate 宏定义一个新子句。类似于 Python 的range,你有一个start, stop, step。这是第一次尝试:
(defmacro-clause (for var start start stop stop step step)
(if (minusp step)
`(for ,var from ,start downto ,stop by (- ,step))
`(for ,var from ,start to ,stop by ,step)))
它使用迭代的to 和downto 关键字处理增加和减少范围。 (请注意,与 Python 不同,这些包括 stop 值。)
这可以根据需要工作
(iter (for x start 5 stop 3 step -1)
(collect x))
;; => (5 4 3)
(iter (for x start 2 stop 5 step 1)
(collect x))
;; => (3,4,5)
但是它失败了
(let ((a 9)
(b 3)
(c -1))
(iter (for x start a stop b step c)
(collect x)))
iterate 在这些地方需要明确的数字是不是有点怪?像这样的事情没有问题
(iter (for x below (+ 3 3) by (+ 1 1))
(collect x))
具体来说,我的问题是,如何定义一个新的iterate 子句来接受在这些地方绑定到数字的变量?
【问题讨论】:
-
您的问题是您在宏扩展时使用
step。如果它不是数字文字,那将根本不起作用,否则就不会。 -
感谢您的回复@Svante,但我不清楚您的意思。为什么您认为该步骤需要是数字文字而不是表达式?或者,换句话说,宏扩展的哪个方面使它不可接受?
-
您正在评估宏扩展时步骤的符号。实际编译的代码只有其中一个 epansion(无论是正步骤还是负步骤)。
标签: loops macros common-lisp