【发布时间】:2016-12-04 00:17:39
【问题描述】:
我正在尝试将 the original "Calendrical Calculations" paper by Derhowitz and Reingold 中的 Common Lisp 代码翻译成 Clojure。在本文中,有一个名为 sum 的宏,在 Common 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))))
但是,当我在一个函数中使用上面的(例如,下面)
(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 宏系统,但据我所知,let 块中的 gensym 调用创建了一个符号(在本例中为 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)))
非常感谢任何和所有关于如何使这项工作的指针。
【问题讨论】:
标签: clojure macros common-lisp