core: Phase 4 — move atom peripheral ops to the overlay over a host primitive

First host-primitive batch. Adds jolt.host/ref-put! — the minimal mutation
kernel (set/remove a key on a mutable reference cell) the overlay can't express
over core fns — and moves seven atom ops out of the seed:

  swap-vals!/reset-vals!/compare-and-set! compose the native swap!/reset!/deref
  (which already validate and notify watches); get-validator is a slot read;
  add-watch/remove-watch/set-validator! mutate the atom (or its watches table)
  via ref-put!.

atom/swap!/reset!/deref and atom-validate/atom-notify-watches stay native — the
compiler depends on them and they're hot. compare-and-set! keeps value-equality
semantics, matching the prior Janet behavior. Covered by the existing state spec.
This commit is contained in:
Yogthos 2026-06-07 21:22:35 -04:00
parent f410bec2ec
commit 4d5aa8c903
3 changed files with 32 additions and 47 deletions

View file

@ -265,3 +265,24 @@
(defn record? [x] (some? (get x :jolt/deftype)))
;; Jolt has no chunked seqs (Phase 5 territory), so this is always false.
(defn chunked-seq? [x] false)
;; Atom peripheral operations. atom/swap!/reset!/deref stay native — the compiler
;; depends on them and they're hot. swap-vals!/reset-vals!/compare-and-set! compose
;; the native ops (which already validate and notify watches); get-validator reads a
;; slot; add-watch/remove-watch/set-validator! mutate the atom (or its watches
;; sub-table) through the one host primitive jolt.host/ref-put! — the minimal
;; mutation kernel the overlay can't express over core fns (a nil value removes the
;; key). compare-and-set! compares by value, matching the prior Janet behavior.
(defn swap-vals! [a f & args]
(let [old (deref a)] [old (apply swap! a f args)]))
(defn reset-vals! [a newval]
(let [old (deref a)] (reset! a newval) [old newval]))
(defn compare-and-set! [a oldval newval]
(if (= oldval (deref a)) (do (reset! a newval) true) false))
(defn get-validator [a] (get a :validator))
(defn add-watch [a key f]
(jolt.host/ref-put! (get a :watches) key f) a)
(defn remove-watch [a key]
(jolt.host/ref-put! (get a :watches) key nil) a)
(defn set-validator! [a f]
(jolt.host/ref-put! a :validator f) nil)