【发布时间】:2016-07-14 05:38:49
【问题描述】:
在这个页面上提到了这个在 Lisp 中实现类似 C 的 for 循环的宏:https://softwareengineering.stackexchange.com/questions/124930/how-useful-are-lisp-macros
(defmacro for-loop [[sym init check change :as params] & steps]
`(loop [~sym ~init value# nil]
(if ~check
(let [new-value# (do ~@steps)]
(recur ~change new-value#))
value#)))
所以可以在代码中使用以下内容:
(for-loop [i 0 , (< i 10) , (inc i)]
(println i))
如何将此宏转换为在 Racket 语言中使用?
我正在尝试以下代码:
(define-syntax (for-loop) (syntax-rules (parameterize ((sym) (init) (check) (change)) & steps)
`(loop [~sym ~init value# nil]
(if ~check
(let [new-value# (do ~@steps)]
(recur ~change new-value#))
value#))))
但它给出了“错误的语法”错误。
【问题讨论】:
-
所以,
syntax-rules与defmacro有很大不同,Scheme/Racket 与 Clojure 也有很大不同。如果您愿意,您也可以使用宏在 Racket 中实现类似的概念,但看起来会有些不同——Clojure 和 Racket 是相关的语言,但它们并不相同,而且它们肯定不兼容源代码。然而,Racket 已经带有一些非常好的 for 循环,它们本身就是普通的旧宏。 Take a look at the docs for more info! -
有很多有用的,但不是经典的。我们如何在 Racket 中为此编写宏。
-
我已经在回答中提到了如何在 Racket 中实现这一点,但同样值得注意的是,Racket
doloop 与您在问题中提到的for-loop宏几乎相同。但是,我在回答中详细说明了为什么几乎从不使用这种结构。