Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@rm-hull
Last active December 18, 2015 02:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rm-hull/5708459 to your computer and use it in GitHub Desktop.
Save rm-hull/5708459 to your computer and use it in GitHub Desktop.
(ns mod-test.example)
; Something very odd is happening with mod when used with some string values whose content happen to be numbers.
;
; Clearly it shouldn't be called with a string, but this doesn't appear to affect modulo "1", "3", "9", "11"
;
; when the rem function is used with string numbers is not affected in the same way, and appears to operate consistently.
;
; Is this some funky gotcha with javascript, or is it a side-effect of the way clojurescript implements mod?
;
; Looking at http://dev.clojure.org/jira/browse/CLJS-417, I see that mod was re-implemented
; ... changing to js-mod and it behaves as expected
(defn same? [msg a b]
(let [res (if (= a b) "EQUAL" "NOT EQUAL")]
(js/alert (str msg "\n\n" "a: " a "\n" "b: " b "\n\n" res))
res))
; all ok
(same?
"Test #1b - simple range mapped over remainders - rem vs. mod"
(->> (range 20) (map #(rem % "3")))
(->> (range 20) (map #(mod % "3"))))
; fails
(same?
"Test #1a - simple range mapped over remainders - rem vs. mod"
(->> (range 20) (map #(rem % "10")))
(->> (range 20) (map #(mod % "10"))))
; ok
(same?
"Test #2 - simple range mapped over remainders - rem vs. js-mod"
(->> (range 20) (map #(rem % "10")))
(->> (range 20) (map #(js-mod % "10"))))
; note not checking negatives
; Snippet of the generated source:
cljs.core.fix = function(a) {
return 0 <= a ? Math.floor.call(null, a) : Math.ceil.call(null, a)
};
cljs.core.js_mod = function(a, b) {
return a % b
};
cljs.core.mod = function(a, b) {
return(a % b + b) % b
};
cljs.core.quot = function(a, b) {
return cljs.core.fix.call(null, (a - a % b) / b)
};
cljs.core.rem = function(a, b) {
var c = cljs.core.quot.call(null, a, b);
return a - b * c
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment