From 65b4b54b3fa5acc9ad7e87606a87d610c44d8015 Mon Sep 17 00:00:00 2001 From: Yogthos Date: Sun, 7 Jun 2026 18:13:08 -0400 Subject: [PATCH] core: move lazy-seq and lazy-cat to the overlay lazy-seq wraps its body in (make-lazy-seq (fn* [] (coll->cells (do ...)))); lazy-cat wraps each coll in lazy-seq and concats (concat is already lazy). Both user-facing, in 30-macros. Also drop two now-stale comments. Laziness preserved (lazy-seqs-spec 20/20, including infinite/self-referential). conformance 228x3, fixpoint, clojure-test-suite 3930, full suite green. --- jolt-core/clojure/core/30-macros.clj | 14 +++++++++++--- src/jolt/core.janet | 19 +------------------ 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/jolt-core/clojure/core/30-macros.clj b/jolt-core/clojure/core/30-macros.clj index cad7072..8678a57 100644 --- a/jolt-core/clojure/core/30-macros.clj +++ b/jolt-core/clojure/core/30-macros.clj @@ -83,7 +83,6 @@ steps (map (fn [f] `(if (nil? ~g) nil (->> ~g ~f))) forms)] `(let [~g ~expr ~@(thread-binds g steps)] ~(if (empty? steps) g (last steps))))) -;; cond-> stays in Janet (the compiler uses it); cond->> (thread-last) is safe. (defmacro cond->> [expr & clauses] (let [g (fresh-sym) steps (map (fn [pair] `(if ~(first pair) (->> ~g ~(second pair)) ~g)) @@ -137,8 +136,7 @@ ;; --- protocols, records, types --------------------------------------------- ;; These emit Jolt's protocol/type special forms (protocol-dispatch, -;; register-method, make-reified, deftype). The :jolt/protocol value built by -;; defprotocol is an opaque tagged struct — it self-evaluates (see eval-form). +;; register-method, make-reified, deftype). ;; Group a flat seq that starts with a head symbol followed by its list specs ;; into [[head spec spec ...] ...] runs. Used by extend-protocol and defrecord. @@ -217,3 +215,13 @@ (def ~arrow (fn* ~fields (~dot ~@fields))) (def ~mapf (fn* [~m] (~arrow ~@(map (fn [f] `(get ~m ~(keyword (name f)))) fields)))) ~@(map (fn [g] (impl (first g) (rest g))) (group-by-head body))))) + +;; --- laziness -------------------------------------------------------------- +;; lazy-seq defers its body: make-lazy-seq holds a thunk that, when forced, +;; realizes the body to cells. lazy-cat wraps each coll in a lazy-seq and concats +;; (concat is itself lazy, so no outer wrapping needed). +(defmacro lazy-seq [& body] + `(make-lazy-seq (fn* [] (coll->cells (do ~@body))))) + +(defmacro lazy-cat [& colls] + `(concat ~@(map (fn [c] `(lazy-seq ~c)) colls))) diff --git a/src/jolt/core.janet b/src/jolt/core.janet index 3cac781..40a9190 100644 --- a/src/jolt/core.janet +++ b/src/jolt/core.janet @@ -1466,21 +1466,6 @@ (defn core-disj [s & ks] (if (set? s) (apply phs-disj s ks) (error "disj expects a set"))) -(defn core-lazy-seq [& body] - @[{:jolt/type :symbol :ns nil :name "make-lazy-seq"} - @[{:jolt/type :symbol :ns nil :name "fn*"} [] - @[{:jolt/type :symbol :ns nil :name "coll->cells"} - @[{:jolt/type :symbol :ns nil :name "do"} ;body]]]]) - -(defn core-lazy-cat [& colls] - "Macro: (lazy-cat & colls) — concatenate lazy sequences, wrapping each coll in lazy-seq. - concat is now lazy, so no outer make-lazy-seq wrapping is needed." - (def concat-form @[]) - (array/push concat-form {:jolt/type :symbol :ns nil :name "concat"}) - (each c colls - (array/push concat-form @[{:jolt/type :symbol :ns nil :name "lazy-seq"} c])) - concat-form) - (defn core-set [coll] (apply core-hash-set (realize-for-iteration coll))) @@ -3026,8 +3011,6 @@ "list" core-list "set?" core-set? "disj" core-disj - "lazy-seq" core-lazy-seq - "lazy-cat" core-lazy-cat "coll->cells" coll->cells "make-lazy-seq" make-lazy-seq "str" core-str @@ -3255,7 +3238,7 @@ (defn core-macro-names "Set of core binding names that are macros." [] - @{"when-let" true "lazy-seq" true "lazy-cat" true}) + @{"when-let" true}) (def init-core! (fn [& args]