%) behaves differently than the Clojure
modfunction with negative operators
System.out.println("5 % 2 = " + (5 % 2)); // 1
(mod -7 2) ; 1
System.out.println("-2 % 7" + (-2 % 7)); // -2
(mod -2 7) ; 5
(rem -2 7) ; -2
The Java behaviour is explained more clearly by the JLS, here.
remshould be the Clojure equivalent if you want to support the same behaviour as Java.
Why would the behaviour of negative numbers and the mod operator ever be useful? One algorithm that uses this is Zeller's Congruence which allows you to determine the day of the week if you know the date.
Defining the algorithm in Clojure is simple:
[day-of-month month year century]
(mod (+ day-of-month
(int (/ (* 26 (inc month)) 10))
(int (/ year 4))
(int (/ century 4))
(- (* 2 century))) 7)))
The algorithm is slightly strange in that January and February need to be treated as the 13th and 14th of the previous month. We can encapsulate this ugliness behind a nicer interface.
(zipmap months [13 14 3 4 5 6 7 8 9 10 11 12]))
[day month year]
(let [month-num (get month-to-number month)
year-int (if (or (= month-num 13) (= month-num 14)) (dec year) year)]
Now we can try this out:
user> (day-of-week 22 'November 1963) ; JFK assassination
user> (day-of-week 20 'July 1969) ; Apollo Moon landing
user> (day-of-week 27 'April 2009)
Of course, any sane person would actually use a built in library function to do this! My rambling point is just that, Java
%is not the same as Clojure