Add Clojure atom aliases to (std misc atom) and re-export from prelude
ober
fb3674d0c169e0a5d49d7bf8c5a53701871d3a66
--- a/lib/jerboa/prelude.sls +++ b/lib/jerboa/prelude.sls @@ -209,6 +209,16 @@ ;; ---- std/ergo ---- using : maybe list-of? + ;; ---- std/misc/atom (Gerbil atom + Clojure aliases) ---- + ;; Gerbil-style: + atom atom? atom-deref atom-reset! atom-swap! atom-update! + ;; Clojure-style aliases (familiar to clojure users) + deref reset! swap! compare-and-set! + + ;; ---- std/misc/shared (atomic cell with CAS) ---- + make-shared shared? shared-ref shared-set! + shared-update! shared-cas! shared-swap! + ;; ---- AI compatibility aliases ---- ;; Common names LLMs hallucinate from Racket/Gerbil/Gambit/CL training data. ;; These are thin aliases so AI-generated code works on the first try. @@ -231,7 +241,8 @@ with-input-from-string with-output-to-string iota 1+ 1- partition - make-date make-time) + make-date make-time + atom?) (only (jerboa core) def def* defrule defrules defstruct defclass defmethod @@ -263,7 +274,9 @@ (std datetime) (std debug pp) (std csv) - (std ergo)) + (std ergo) + (std misc atom) + (std misc shared)) ;; ---- AI compatibility aliases ---- (define hash-has-key? hash-key?) --- a/lib/std/misc/atom.sls +++ b/lib/std/misc/atom.sls @@ -1,17 +1,31 @@ #!chezscheme ;;; :std/misc/atom -- Thread-safe mutable reference cells ;;; -;;; Gerbil's atom API: a mutable cell with mutex-protected updates. -;;; Used for background thread state (caches, indices, flags). +;;; Gerbil-style atom API plus Clojure-style aliases for clojure users. ;;; -;;; (define counter (atom 0)) -;;; (atom-deref counter) ;; → 0 -;;; (atom-reset! counter 42) ;; set to 42 -;;; (atom-swap! counter add1) ;; atomically apply function → 1 -;;; (atom-update! counter + 10) ;; atomically apply with args → 11 +;;; Native / Gerbil style: +;;; (define counter (atom 0)) +;;; (atom-deref counter) ;; → 0 +;;; (atom-reset! counter 42) ;; set to 42 +;;; (atom-swap! counter add1) ;; atomically apply function → 1 +;;; (atom-update! counter + 10) ;; atomically apply with args → 11 +;;; +;;; Clojure style (same semantics, familiar names): +;;; (define counter (atom 0)) ;; same constructor +;;; (deref counter) ;; like Clojure's @counter +;;; (reset! counter 42) ;; returns 42 +;;; (swap! counter + 1) ;; (apply + @counter 1) → 43, variadic +;;; (swap! counter inc) ;; → 44 +;;; (compare-and-set! counter 44 100) ;; CAS → #t/#f (library (std misc atom) - (export atom atom? atom-deref atom-reset! atom-swap! atom-update!) + (export + ;; ---- Gerbil-style native names ---- + atom atom? atom-deref atom-reset! atom-swap! atom-update! + ;; ---- Clojure-style aliases ---- + ;; Note: no `atom?` alias — Clojure doesn't expose one either. + ;; Use atom? (the existing predicate) or shared? from (std misc shared). + deref reset! swap! compare-and-set!) (import (except (chezscheme) atom?)) @@ -49,4 +63,32 @@ (atom-rec-val-set! a new-val) new-val))) + ;; ========================================================================= + ;; Clojure-style aliases + ;; + ;; Clojure semantics (for context): + ;; @a / (deref a) → read current value + ;; (reset! a v) → set, returns new value + ;; (swap! a f args...) → (apply f @a args), returns new value + ;; (compare-and-set! a o n) → CAS, returns #t if swapped, #f otherwise + ;; ========================================================================= + + (define deref atom-deref) + + (define reset! atom-reset!) + + ;; Clojure's swap! is variadic: (swap! a f x y) calls (f @a x y). + ;; That's exactly atom-update!'s signature. + (define swap! atom-update!) + + (define (compare-and-set! a expected new-val) + ;; Atomically: if current value is equal? to expected, replace + ;; with new-val and return #t. Otherwise return #f. + (with-mutex (atom-rec-mtx a) + (if (equal? (atom-rec-val a) expected) + (begin + (atom-rec-val-set! a new-val) + #t) + #f))) + ) ;; end library --- a/lib/std/misc/shared.sls +++ b/lib/std/misc/shared.sls @@ -4,6 +4,9 @@ ;;; A shared cell wraps a value with a mutex for thread-safe access. ;;; Similar to atom but with compare-and-swap semantics. ;;; +;;; For Clojure-style atom/deref/swap!/reset!/compare-and-set! aliases, +;;; see (std misc atom) — that module exposes the clojure-familiar names. +;;; ;;; Usage: ;;; (import (std misc shared)) ;;; (define s (make-shared 0))