Last active
December 18, 2015 02:08
-
-
Save rm-hull/5708459 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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