You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
core: set! mutates topmost dynamic binding instead of being a no-op
set! was defined as a no-op macro on the theory that it was just a
JVM compiler directive. But Clojure's set! does double duty: on the
JVM it mutates fields (irrelevant to mino), and on dynamic vars it
mutates the thread-local binding frame inside an enclosing binding.
The latter shape is portable Clojure code that mino was silently
ignoring -- counters built on (binding [*c* 0] (set! *c* (inc *c*)))
stayed at 0.
Added prim_set_dyn_binding (set-dyn-binding!) which walks ctx->dyn_
stack, finds the topmost binding for the named symbol, mutates its
val, and returns the new value. Throws "Can't change/establish root
binding" when no binding frame is active for the name, matching JVM
Clojure's runtime contract. set! macro now expands to a
set-dyn-binding! call with a quoted target symbol.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
"Returns a map of symbol->value for the active dynamic bindings, or nil if no binding frames are active."},
995
1039
{"with-bindings*", prim_with_bindings_star,
996
1040
"(with-bindings* bindings-map fn) — pushes the bindings as a dynamic frame and invokes fn with no args."},
1041
+
{"set-dyn-binding!", prim_set_dyn_binding,
1042
+
"(set-dyn-binding! 'name value) — mutate the topmost active dynamic binding for `name`. Returns the value. Throws when no binding frame is active for `name`. Backs (set! *var* expr)."},
997
1043
{"set-fail-alloc-at!", prim_set_fail_alloc_at,
998
1044
"Make the n-th GC allocation fail (simulated OOM). Pass 0 to disable."},
0 commit comments