我在尝试将Common Lisp代码the original "Calendrical Calculations" paper by Derhowitz and Reingold翻译为Clojure。在本文中有一个名为sum
这是Common Lisp中给出将宏从Common Lisp翻译为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 (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))))
然而,宏当我使用上面的函数(例如,以下同)
(defn absolute-from-gregorian [date]
;; Absolute date equivalent to the Gregorian date.
(let [month (extract-month date)
year (extract-year date)]
; Return
(+ (extract-day date) ;; Days so far this month.
(sum ;; Days in prior months this year.
(last-day-of-gregorian-month m year) m 1 (< m month))
(* 365 (dec year)) ;; Days in prior years.
(quotient (dec year) 4) ;; Julian leap days in prior years...
(- ;; ... minus prior century years...
(quotient (dec year) 100))
(quotient ;; ...plus prior years divisible...
(dec year) 400)))) ;; ... by 400.
我得到类似如下的错误:
CompilerException java.lang.RuntimeException: Unable to resolve
symbol: G__53 in this context, compiling:(NO_SOURCE_PATH:165:8)
我与Lisp的/ Clojure的宏系统几乎完全陌生的,但是从我可以确定它说,gensym
调用在let
块创建了一个符号(在这种情况下G__53
),其上调用,但这不存在。 这是有道理的,但我怀疑它不是原始代码的意图 - 但是,我对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)))
任何和所有的指针就如何使这项工作十分赞赏。
非常感谢。在发布我的问题后,我继续处理这个问题,并确定使用'recur'的循环是合适的,但对Clojure/Lisp宏还不太了解,我还没有弄清楚如何将它们放在一起。看起来我必须拿起[关于Clojure宏的书](https://pragprog.com/book/cjclojure/mastering-clojure-macros),花些时间学习更多关于它们的知识。 –