core: port when-let to the overlay — finishes the Phase 3 macro migration
Last core macro still in Janet. Goes in 00-syntax (not 30-macros with its if-let/if-some/when-some siblings) because 20-coll's not-empty uses it and 20-coll loads before 30. Via `let` so the binding form may destructure, matching Clojure — the old Janet version used let* and wouldn't. Drops core-when-let + the sym* helper + the intern entry, and empties core-macro-names (no seed binding is a macro anymore).
This commit is contained in:
parent
77e3e3afcf
commit
8bc5bd6f61
3 changed files with 16 additions and 20 deletions
|
|
@ -321,3 +321,12 @@
|
|||
;; (for handles :when/:let/:while and multiple bindings).
|
||||
(defmacro doseq [bindings & body]
|
||||
`(do (count (for ~bindings (do ~@body nil))) nil))
|
||||
|
||||
;; when-let must live in this (early) tier, not 30-macros with its if-let/if-some/
|
||||
;; when-some siblings: 20-coll uses it (not-empty), and 20-coll loads before 30. The
|
||||
;; name binds only in the taken branch (temp# tests the value); via `let` so the
|
||||
;; binding form may itself destructure, matching Clojure.
|
||||
(defmacro when-let [bindings & body]
|
||||
(let [form (bindings 0) tst (bindings 1)]
|
||||
`(let [temp# ~tst]
|
||||
(if temp# (let [~form temp#] ~@body) nil))))
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
`(let [temp# ~tst]
|
||||
(if temp# (let [~form temp#] ~then) ~else))))
|
||||
|
||||
;; when-let lives in 00-syntax (not here): 20-coll uses it, which loads before this tier.
|
||||
|
||||
(defmacro if-some [bindings then & [else]]
|
||||
(let [form (bindings 0) tst (bindings 1)]
|
||||
`(let [temp# ~tst]
|
||||
|
|
|
|||
|
|
@ -2048,23 +2048,8 @@
|
|||
{:jolt/type :symbol :ns nil :name (string prefix-string n)})
|
||||
|
||||
|
||||
# if-let / when-let / if-some / when-some bind the name ONLY in the then/body
|
||||
# branch — the else branch must see the surrounding scope, not the binding (so
|
||||
# (let [x 5] (if-let [x nil] x x)) returns 5, like Clojure). Achieved with a fresh
|
||||
# temp around the if; the name is rebound to the temp inside the taken branch only.
|
||||
(defn- sym* [name] {:jolt/type :symbol :ns nil :name name})
|
||||
|
||||
(defn core-when-let
|
||||
"Macro: (when-let [binding val-expr] & body)"
|
||||
[bindings & body]
|
||||
(def form-sym (in bindings 0))
|
||||
(def val-form (in bindings 1))
|
||||
(def temp (gensym "when_let__"))
|
||||
@[(sym* "let*") @[temp val-form]
|
||||
@[(sym* "if") temp
|
||||
@[(sym* "let*") @[form-sym temp] @[(sym* "do") ;body]]
|
||||
nil]])
|
||||
|
||||
# if-let/when-let/if-some/when-some now live in the Clojure overlay
|
||||
# (core/30-macros.clj) as defmacros.
|
||||
|
||||
(defn core-push-thread-bindings [b] (push-thread-bindings b))
|
||||
(defn core-pop-thread-bindings [] (pop-thread-bindings))
|
||||
|
|
@ -3090,7 +3075,6 @@
|
|||
"add-watch" core-add-watch
|
||||
"remove-watch" core-remove-watch
|
||||
"not" core-not
|
||||
"when-let" core-when-let
|
||||
"derive" core-derive
|
||||
"isa?" core-isa?
|
||||
"parents" core-parents
|
||||
|
|
@ -3156,9 +3140,10 @@
|
|||
"*assert" true})
|
||||
|
||||
(defn core-macro-names
|
||||
"Set of core binding names that are macros."
|
||||
"Set of core binding names that are macros. Empty now that every core macro
|
||||
lives in the Clojure overlay (clojure.core.*-syntax / *-macros tiers)."
|
||||
[]
|
||||
@{"when-let" true})
|
||||
@{})
|
||||
|
||||
(def init-core!
|
||||
(fn [& args]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue