core: zero?/pos?/every? to 00-syntax, char? to the overlay; fix rest/next over sets and maps
Round 4 of the seed shrink. zero?, pos?, every? move to the syntax tier
(empty? and the analyzer use them — raw def+fn* per the file constraint);
char? joins the tagged-value predicates in 20-coll. coll? stays seed: host
set? doesn't cover sorted sets (filed jolt-dpn) and the tag check from the
overlay would hit the sorted-coll get trap. pos? guards number? explicitly —
the staged recompile emits bare > as the native janet op, which orders
strings (zero? gets the same guard; spec rows lock both plus neg?).
The canonical every? seq-walks its coll, which exposed that rest/next over
sets, phms, struct maps and sorted colls fell into core-rest's indexed
fall-through and walked the wrapper table's INTERNAL fields — (next #{1 2})
was (nil nil), (clojure.set/subset?) broke. core-rest now seqs those
representations (branches placed AFTER the hot vector/lazy paths; the first
ordering cost seq-pipe 4x). Suite rises 4700 -> 4703; baseline 4660 -> 4695.
even?/odd? are back in the seed after the bench A/B: (filter even? ...) pays
an extra call layer per element through the overlay (seq-pipe 262 -> 1100ms).
They join the perf-wall list with the lazy hot fns.
This commit is contained in:
parent
407d656240
commit
a1a9fd9949
6 changed files with 97 additions and 37 deletions
|
|
@ -14,6 +14,35 @@
|
|||
;; (backend/recompile-defns!) once the analyzer is alive — same lifecycle as
|
||||
;; the defmacro expanders.
|
||||
|
||||
;; zero?/pos?/every? live HERE (not 20-coll): empty? below calls zero?, and
|
||||
;; the self-hosted analyzer — compiled right after the kernel tier — uses all
|
||||
;; three. Raw def+fn* per the file constraint. zero? checks number? itself
|
||||
;; (= doesn't throw); pos? inherits throwing from >.
|
||||
(def zero?
|
||||
(fn* zero? [x]
|
||||
(if (number? x)
|
||||
(= x 0)
|
||||
(throw (str "zero? requires a number, got: " x)))))
|
||||
|
||||
;; pos? checks number? explicitly: this tier is recompiled by the staged pass,
|
||||
;; where a bare (> x 0) emits the native janet op that happily orders strings
|
||||
;; (the documented native-ops relaxation) — the guard keeps Clojure's throw.
|
||||
(def pos?
|
||||
(fn* pos? [x]
|
||||
(if (number? x)
|
||||
(> x 0)
|
||||
(throw (str "pos? requires a number, got: " x)))))
|
||||
|
||||
;; Canonical every?: short-circuits on the first falsey result, so infinite
|
||||
;; seqs with an early counterexample terminate.
|
||||
(def every?
|
||||
(fn* every? [pred coll]
|
||||
(if (nil? (seq coll))
|
||||
true
|
||||
(if (pred (first coll))
|
||||
(recur pred (next coll))
|
||||
false))))
|
||||
|
||||
;; empty?/keys/vals live HERE (not 20-coll) because the expanders below call
|
||||
;; them at expansion time, which first happens during the kernel-tier compile.
|
||||
;; empty? keeps O(1) dispatch for counted things; only the lazy/list fallback
|
||||
|
|
|
|||
|
|
@ -14,14 +14,8 @@
|
|||
;; neg? throws on non-numbers via <, as Clojure's Numbers.isNeg does.
|
||||
(defn neg? [x] (< x 0))
|
||||
|
||||
;; even?/odd? accept any integral number (jolt has one number type, so 2.0
|
||||
;; counts) and throw otherwise — Clojure's IllegalArgumentException wording.
|
||||
(defn even? [n]
|
||||
(if (integer? n)
|
||||
(zero? (rem n 2))
|
||||
(throw (str "Argument must be an integer: " n))))
|
||||
|
||||
(defn odd? [n] (not (even? n)))
|
||||
;; even?/odd? stay in the seed: (filter even? ...) is idiomatic-hot and the
|
||||
;; overlay versions cost an extra call layer per element (seq-pipe bench 4x).
|
||||
|
||||
;; Base is (hash-map), not the {} literal: a literal map is a struct that doesn't
|
||||
;; canonicalize collection keys across representations (a {:a 1} literal vs
|
||||
|
|
@ -569,6 +563,7 @@
|
|||
(defn record? [x] (some? (get x :jolt/deftype)))
|
||||
(defn uuid? [x] (= (get x :jolt/type) :jolt/uuid))
|
||||
(defn inst? [x] (= (get x :jolt/type) :jolt/inst))
|
||||
(defn char? [x] (= (get x :jolt/type) :jolt/char))
|
||||
|
||||
;; inst-ms: epoch milliseconds of an instant; throws on a non-inst (Clojure
|
||||
;; protocol behavior).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue