core: move promoting/unchecked arithmetic aliases, int?, num to the overlay
Jolt numbers don't overflow, so +'/-'/*'/inc'/dec' and the whole unchecked-* family are just the checked ops — now one-line defs in core/20-coll.clj instead of ~25 seed bindings. int? and num move the same way. unchecked-divide-int now goes through quot, so dividing by zero throws like the JVM instead of silently truncating infinity. unchecked-int/long gain char handling via int, matching Clojure ((unchecked-int \a) => 97). The masking byte/short/char coercions are not aliases and stay in the seed for a later round. Also drops a second duplicate set of unchecked defns that was shadowing the first at module load.
This commit is contained in:
parent
826bee29d4
commit
9ac0f54e72
3 changed files with 73 additions and 39 deletions
|
|
@ -848,3 +848,37 @@
|
|||
;; there, so vector? can't separate them and lists read as ifn?.
|
||||
(defn ifn? [x]
|
||||
(or (fn? x) (keyword? x) (symbol? x) (map? x) (set? x) (vector? x) (var? x)))
|
||||
|
||||
;; Auto-promoting (') and unchecked arithmetic. Jolt numbers don't overflow,
|
||||
;; so all of these are the checked ops; fixed arities mirror Clojure's
|
||||
;; signatures. unchecked-divide-int goes through quot, so dividing by zero
|
||||
;; throws as on the JVM (the old seed fn silently truncated infinity).
|
||||
(def +' +)
|
||||
(def -' -)
|
||||
(def *' *)
|
||||
(def inc' inc)
|
||||
(def dec' dec)
|
||||
(defn unchecked-add [x y] (+ x y))
|
||||
(defn unchecked-subtract [x y] (- x y))
|
||||
(defn unchecked-multiply [x y] (* x y))
|
||||
(defn unchecked-negate [x] (- x))
|
||||
(defn unchecked-inc [x] (+ x 1))
|
||||
(defn unchecked-dec [x] (- x 1))
|
||||
(def unchecked-add-int unchecked-add)
|
||||
(def unchecked-subtract-int unchecked-subtract)
|
||||
(def unchecked-multiply-int unchecked-multiply)
|
||||
(def unchecked-negate-int unchecked-negate)
|
||||
(def unchecked-inc-int unchecked-inc)
|
||||
(def unchecked-dec-int unchecked-dec)
|
||||
(defn unchecked-divide-int [x y] (quot x y))
|
||||
(defn unchecked-remainder-int [x y] (rem x y))
|
||||
(defn unchecked-int [x] (int x))
|
||||
(def unchecked-long unchecked-int)
|
||||
|
||||
;; int? is integer? on jolt: one number type, so fixed-precision and
|
||||
;; arbitrary-precision integers coincide.
|
||||
(defn int? [x] (integer? x))
|
||||
|
||||
;; num: Clojure coerces to java.lang.Number; jolt just checks.
|
||||
(defn num [x]
|
||||
(if (number? x) x (throw (str "num requires a number, got: " x))))
|
||||
|
|
|
|||
|
|
@ -2020,7 +2020,8 @@
|
|||
(def core-long (fn [x] (if (core-char? x) (x :ch) (math/trunc x))))
|
||||
(def core-double (fn [x] (* 1.0 (if (core-char? x) (x :ch) x))))
|
||||
(def core-float core-double)
|
||||
(def core-num (fn [x] (if (number? x) x (error (string "num requires a number, got " (type x))))))
|
||||
# num and the unchecked-*/promoting-' arithmetic live in the Clojure
|
||||
# collection tier (core/20-coll.clj) — jolt numbers don't overflow.
|
||||
(defn core-char [x]
|
||||
"(char code-or-char) -> a character value."
|
||||
(cond
|
||||
|
|
@ -2028,10 +2029,6 @@
|
|||
(number? x) (make-char (math/trunc x))
|
||||
(string? x) (make-char (in x 0))
|
||||
(error "char expects a number or character")))
|
||||
(def core-unchecked-inc (fn [x] (+ x 1)))
|
||||
(def core-unchecked-dec (fn [x] (- x 1)))
|
||||
(def core-unchecked-add (fn [& xs] (+ ;xs)))
|
||||
(def core-unchecked-subtract (fn [& xs] (- ;xs)))
|
||||
|
||||
# ============================================================
|
||||
# Hash
|
||||
|
|
@ -2626,15 +2623,8 @@
|
|||
(error "persistent! requires a transient")))
|
||||
|
||||
# Unchecked arithmetic — Jolt numbers don't overflow, so these are plain ops.
|
||||
(defn core-unchecked-add [a b] (+ a b))
|
||||
(defn core-unchecked-subtract [a b] (- a b))
|
||||
(defn core-unchecked-multiply [a b] (* a b))
|
||||
(defn core-unchecked-negate [a] (- a))
|
||||
(defn core-unchecked-inc [a] (+ a 1))
|
||||
(defn core-unchecked-dec [a] (- a 1))
|
||||
(defn core-unchecked-divide-int [a b] (math/trunc (/ a b)))
|
||||
(defn core-unchecked-remainder-int [a b] (% a b))
|
||||
(defn core-unchecked-int [a] (math/trunc a))
|
||||
# unchecked-* arithmetic lives in the Clojure collection tier
|
||||
# (core/20-coll.clj); only the masking byte/short/char coercions remain above.
|
||||
|
||||
# Hashing helpers
|
||||
# Hashes are masked to 24 bits at each step so intermediate products stay within
|
||||
|
|
@ -2700,13 +2690,6 @@
|
|||
"/" core-/
|
||||
"inc" core-inc
|
||||
"dec" core-dec
|
||||
# auto-promoting variants — Jolt numbers don't overflow, so these are the
|
||||
# same as their non-quoted counterparts
|
||||
"+'" core-+
|
||||
"-'" core-sub
|
||||
"*'" core-*
|
||||
"inc'" core-inc
|
||||
"dec'" core-dec
|
||||
"mod" core-mod
|
||||
"rem" core-rem
|
||||
"quot" core-quot
|
||||
|
|
@ -2761,27 +2744,10 @@
|
|||
"assoc!" core-assoc!
|
||||
"dissoc!" core-dissoc!
|
||||
"pop!" core-pop!
|
||||
"unchecked-add" core-unchecked-add
|
||||
"unchecked-add-int" core-unchecked-add
|
||||
"unchecked-subtract" core-unchecked-subtract
|
||||
"unchecked-subtract-int" core-unchecked-subtract
|
||||
"unchecked-multiply" core-unchecked-multiply
|
||||
"unchecked-multiply-int" core-unchecked-multiply
|
||||
"unchecked-negate" core-unchecked-negate
|
||||
"unchecked-negate-int" core-unchecked-negate
|
||||
"unchecked-inc" core-unchecked-inc
|
||||
"unchecked-inc-int" core-unchecked-inc
|
||||
"unchecked-dec" core-unchecked-dec
|
||||
"unchecked-dec-int" core-unchecked-dec
|
||||
"unchecked-divide-int" core-unchecked-divide-int
|
||||
"unchecked-remainder-int" core-unchecked-remainder-int
|
||||
"unchecked-int" core-unchecked-int
|
||||
"unchecked-long" core-unchecked-int
|
||||
"hash-combine" core-hash-combine
|
||||
"hash-ordered-coll" core-hash-ordered-coll
|
||||
"hash-unordered-coll" core-hash-unordered-coll
|
||||
"gensym" gensym
|
||||
"int?" core-integer?
|
||||
"compare" core-compare
|
||||
"type" core-type
|
||||
"slurp" core-slurp
|
||||
|
|
@ -2946,7 +2912,6 @@
|
|||
"long" core-long
|
||||
"double" core-double
|
||||
"float" core-float
|
||||
"num" core-num
|
||||
"char" core-char
|
||||
"char?" core-char?
|
||||
# Hash
|
||||
|
|
|
|||
|
|
@ -157,3 +157,38 @@
|
|||
["parse-boolean case" "nil" "(parse-boolean \"True\")"]
|
||||
["parse-boolean junk" "nil" "(parse-boolean \"yes\")"]
|
||||
["parse-boolean throws" :throws "(parse-boolean true)"])
|
||||
|
||||
# Jolt numbers don't overflow, so the auto-promoting (') and unchecked
|
||||
# variants are aliases of the checked ops (overlay defs, core/20-coll.clj).
|
||||
(defspec "numbers / promoting & unchecked aliases"
|
||||
["+'" "3" "(+' 1 2)"]
|
||||
["-'" "3" "(-' 5 2)"]
|
||||
["*'" "12" "(*' 3 4)"]
|
||||
["inc'" "6" "(inc' 5)"]
|
||||
["dec'" "4" "(dec' 5)"]
|
||||
["unchecked-add" "5" "(unchecked-add 2 3)"]
|
||||
["unchecked-add-int" "5" "(unchecked-add-int 2 3)"]
|
||||
["unchecked-subtract" "3" "(unchecked-subtract 5 2)"]
|
||||
["unchecked-subtract-int" "3" "(unchecked-subtract-int 5 2)"]
|
||||
["unchecked-multiply" "12" "(unchecked-multiply 3 4)"]
|
||||
["unchecked-multiply-int" "12" "(unchecked-multiply-int 3 4)"]
|
||||
["unchecked-negate" "-5" "(unchecked-negate 5)"]
|
||||
["unchecked-negate-int" "-5" "(unchecked-negate-int 5)"]
|
||||
["unchecked-inc" "2" "(unchecked-inc 1)"]
|
||||
["unchecked-inc-int" "2" "(unchecked-inc-int 1)"]
|
||||
["unchecked-dec" "0" "(unchecked-dec 1)"]
|
||||
["unchecked-dec-int" "0" "(unchecked-dec-int 1)"]
|
||||
["unchecked-divide-int" "3" "(unchecked-divide-int 7 2)"]
|
||||
["unchecked-divide-int negative truncates toward zero" "-3" "(unchecked-divide-int -7 2)"]
|
||||
["unchecked-divide-int by zero throws" :throws "(unchecked-divide-int 1 0)"]
|
||||
["unchecked-remainder-int" "1" "(unchecked-remainder-int 7 2)"]
|
||||
["unchecked-remainder-int negative" "-1" "(unchecked-remainder-int -7 2)"]
|
||||
["unchecked-int truncates" "3" "(unchecked-int 3.7)"]
|
||||
["unchecked-int negative" "-3" "(unchecked-int -3.7)"]
|
||||
["unchecked-long" "3" "(unchecked-long 3.7)"]
|
||||
["int? on integer" "true" "(int? 5)"]
|
||||
["int? on double" "false" "(int? 5.5)"]
|
||||
["int? on non-number" "false" "(int? \"5\")"]
|
||||
["num passes a number through" "5" "(num 5)"]
|
||||
["num on a double" "5.5" "(num 5.5)"]
|
||||
["num throws on non-number" :throws "(num \"x\")"])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue