I'm trying to translate the Common Lisp code in the original "Calendrical Calculations" paper by Derhowitz and Reingold to Clojure. In this paper there is a macro named sum
which is given in Common Lisp as
(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))))
and which I've translated to Clojure as
(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))))
However, when I use the above in a function (for example, the following)
(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.
I get an error similar to the following:
CompilerException java.lang.RuntimeException: Unable to resolve
symbol: G__53 in this context, compiling:(NO_SOURCE_PATH:165:8)
I'm almost completely unfamiliar with the Lisp/Clojure macro system, but from what I can determine it's saying that the gensym
invocation in the let
block has created a symbol (in this case G__53
) which is being invoked, but which doesn't exist. That makes sense, but I suspect it's not the intent of the original code - however, I don't know much about Common Lisp and thus I'm not able to figure out A) what the original CL code is trying to do here, and B) how to produce a Clojure equivalent to this.
For what it's worth - the Clojure version of the other functions used in absolute-from-gregorian
are:
(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)))
Any and all pointers as to how to make this work greatly appreciated.