将宏从Common Lisp转换为Clojure

将宏从Common Lisp转换为Clojure,clojure,macros,common-lisp,Clojure,Macros,Common Lisp,我正在尝试将公共Lisp代码翻译成Clojure。在本文中,有一个名为sum的宏,它在公共Lisp中给出如下 (defmacro sum (expression index initial condition) ;; sum expession for index = initial and successive integers, ;; as long as condition holds. (let* ((temp (gensym))) `(do ((,temp 0 (+ ,temp

我正在尝试将公共Lisp代码翻译成Clojure。在本文中,有一个名为
sum
的宏,它在公共Lisp中给出如下

(defmacro sum (expression index initial condition)
;; sum expession for index = initial and successive integers,
;; as long as condition holds.
 (let* ((temp (gensym)))
   `(do ((,temp 0 (+ ,temp ,expression))
         (,index ,initial (i+ ,index))) 
        ((not ,condition) ,temp))))
我把它翻译成Clojure

(defmacro sum [expression index initial condition]
  ; sum expession for index = initial and successive integers,
  ; as long as condition holds.
  (let [temp (gensym)]
    `(do ((~temp 0 (+ ~temp ~expression))
          (~index ~initial (inc ~index))) 
         ((not ~condition) ~temp))))
但是,当我在函数中使用上述内容时(例如,以下内容)

我几乎完全不熟悉Lisp/Clojure宏系统,但从我可以确定的是,
let
块中的
gensym
调用创建了一个正在调用但不存在的符号(在本例中为
G_u53
)。这是有道理的,但我怀疑这不是原始代码的意图——然而,我对Common Lisp知之甚少,因此我无法理解A)原始CL代码在这里试图做什么,以及B)如何生成与此等效的Clojure

值得一提的是,
absolute from gregorian
中使用的其他函数的Clojure版本是:

(defn quotient [m n]
  (int (Math/floor (/ m n))))

(defn extract-month [date]
  (first date))

(defn extract-day [date]
  (second date))

(defn extract-year [date]
  (second (rest date)))

任何和所有关于如何使这项工作得到高度赞赏的指针。

do
在common中,lisp的行为与clojure中的
do
完全不同。您必须查找
do
实际上做了什么(它在common lisp中是一个循环构造,在clojure中是一个分组构造),并找出如何完成同样的事情。

do
在common lisp中的行为与clojure中的
do
完全不同。您必须查找
所做的
实际做的事情(在common lisp中是循环构造,在clojure中是分组构造),并找出如何完成相同的事情。

这可以用clojure中的
循环
构造来表示:

(defmacro sum [expression index initial condition]
  ; sum expession for index = initial and successive integers,
  ; as long as condition holds.
  `(loop [~index ~initial temp# 0]
     (if ~condition 
       (recur (inc ~index) (+ temp# ~expression))
       temp#)))
例如:

(sum (* x x) x 1 (<= x 3)) ;; => 14

这可以用Clojure中的
循环
构造表示:

(defmacro sum [expression index initial condition]
  ; sum expession for index = initial and successive integers,
  ; as long as condition holds.
  `(loop [~index ~initial temp# 0]
     (if ~condition 
       (recur (inc ~index) (+ temp# ~expression))
       temp#)))
例如:

(sum (* x x) x 1 (<= x 3)) ;; => 14

非常感谢。在发布我的问题后,我继续研究这个问题,并确定使用
recur
的循环是合适的,但对Clojure/Lisp宏了解不多,我还没有弄清楚如何将其组合在一起。看来我得接电话了,花点时间学习更多关于他们的知识。非常感谢。在发布我的问题后,我继续研究这个问题,并确定使用
recur
的循环是合适的,但对Clojure/Lisp宏了解不多,我还没有弄清楚如何将其组合在一起。看来我得接电话,花点时间了解更多关于他们的情况。
(reduce + (map #(last-day-of-gregorian-month % year) (range 1 month)))