core: staged recompile for early defns; keys/vals/empty? leave the seed (jolt-4j3)
recompile-defns! is the defn analog of recompile-macros!: pre/at-kernel
overlay defns (00-syntax's destructure and friends; the kernel tier too in
interpret mode) load as interpreted closures, the evaluator stashes their fn
source on the var (:defn-src, scoped by a flag only api/load-core-overlay!
sets), and the end-of-init pass compiles them and swaps the var root. With
that in place, keys/vals/empty? — the fns the 00-syntax expanders call at
expansion time — move to the top of 00-syntax as raw fn* defs (canonical:
keys/vals project (seq m), so sorted maps come back in comparator order and
(keys {}) is nil; empty? keeps O(1) count dispatch with seq's cell check only
for the lazy/list fallback). The sorted tier drops its now-dead :keys/:vals
ops.
Correctness fixes that surfaced once the gate was run with a REAL exit code
(the previous 'jpm test | grep' gates reported grep's exit and masked spec
failures across #48-#50):
- map conj is strict again: a non-nil/non-map arg must be a 2-element vector
('Vector arg to map conj must be a pair'), and merge inherits it — the
batch-2 canonical merge had silently dropped the validation
- conj onto a lazy seq prepends (it fell into the MAP fallback); upstream
clojure.data/diff relies on (conj seq x) via set/union over keys, so diff
now matches Clojure exactly
- (seq {}) / (seq #{}) / empty phm are nil, not ()
- key/val are strict (a plain vector is not an entry); find mints a REAL
entry as the first entry of a one-entry map, nil values intact
- the sci avoid-method-too-large stub passes its registry map through
instead of returning a raw host table (strict conj rejected it; sci's
clojure-core registry is also no longer discarded)
Test updates: lazy-infinite pins take-nth realization at 5 (was 7 — the
canonical lazy impl realizes fewer); self-host asserts the analyzer IS loaded
in interpret mode (compiled expanders, PR #50) and is NOT in the
:compile-macros? false oracle. 18 new maps-spec rows.
Gate: jpm test exit 0 (verified directly, not through a pipe), conformance
326x3, suite 4698 >= 4660.
This commit is contained in:
parent
e6f562c175
commit
63eb6eca6e
11 changed files with 176 additions and 50 deletions
|
|
@ -634,17 +634,18 @@
|
|||
;; --- Phase 2 leaf batch 2 (jolt-ded): canonical Clojure ports ----------------
|
||||
;; key/val/find first — merge-with and memoize below use them.
|
||||
|
||||
;; An entry is any 2-element vector in jolt ((seq m) yields tuples, find
|
||||
;; builds a pvec — both count as entries; Clojure's stricter MapEntry-only
|
||||
;; key/val has no analog here).
|
||||
(defn- map-entryish? [e] (and (vector? e) (= 2 (count e))))
|
||||
(defn key [e] (if (map-entryish? e) (nth e 0) (throw (ex-info "key requires a map entry" {}))))
|
||||
(defn val [e] (if (map-entryish? e) (nth e 1) (throw (ex-info "val requires a map entry" {}))))
|
||||
;; Strict, as in Clojure: an entry is what (seq m) yields (a host tuple), NOT
|
||||
;; a plain vector — (key [1 2]) throws.
|
||||
(defn key [e] (if (map-entry? e) (nth e 0) (throw (ex-info "key requires a map entry" {}))))
|
||||
(defn val [e] (if (map-entry? e) (nth e 1) (throw (ex-info "val requires a map entry" {}))))
|
||||
|
||||
;; find was previously missing from jolt entirely. Presence (contains?), not
|
||||
;; value, decides — so (find {:a nil} :a) is [:a nil]. Works on vectors by index.
|
||||
;; value, decides — so (find {:a nil} :a) is [:a nil]. Works on vectors by
|
||||
;; index. The result must be a REAL entry (key/val are strict), so it is
|
||||
;; minted as the first entry of a one-entry map — nil values survive (the
|
||||
;; map builder switches to a phm when nil is involved).
|
||||
(defn find [m k]
|
||||
(when (contains? m k) [k (get m k)]))
|
||||
(when (contains? m k) (first {k (get m k)})))
|
||||
|
||||
(defn some? [x] (not (nil? x)))
|
||||
(defn true? [x] (= true x))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue