diff --git a/.beads/interactions.jsonl b/.beads/interactions.jsonl index cf2efc3..fe8b7d7 100644 --- a/.beads/interactions.jsonl +++ b/.beads/interactions.jsonl @@ -10,3 +10,4 @@ {"id":"int-10c63325","kind":"field_change","created_at":"2026-06-04T18:40:43.31635Z","actor":"Yogthos","issue_id":"jolt-4z9","extra":{"field":"status","new_value":"closed","old_value":"open"}} {"id":"int-ba29d2c7","kind":"field_change","created_at":"2026-06-04T18:45:52.297233Z","actor":"Yogthos","issue_id":"jolt-gxr","extra":{"field":"status","new_value":"closed","old_value":"open"}} {"id":"int-b7e06923","kind":"field_change","created_at":"2026-06-04T18:55:10.600885Z","actor":"Yogthos","issue_id":"jolt-7n5","extra":{"field":"status","new_value":"closed","old_value":"open"}} +{"id":"int-0d2b12ab","kind":"field_change","created_at":"2026-06-04T18:56:25.718778Z","actor":"Yogthos","issue_id":"jolt-90c","extra":{"field":"status","new_value":"closed","old_value":"open"}} diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 96923de..1186d0d 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -10,6 +10,6 @@ {"_type":"issue","id":"jolt-ytt","title":"HIGH: str semantics — (str nil)='nil' should be '', (str :b)='b' should be ':b'","status":"closed","priority":2,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:56Z","created_by":"Yogthos","updated_at":"2026-06-04T18:33:45Z","closed_at":"2026-06-04T18:33:45Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"jolt-9sb","title":"HIGH: destructuring gaps (nested seq, :strs, nested map, fn-param)","status":"closed","priority":2,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:55Z","created_by":"Yogthos","updated_at":"2026-06-04T18:31:24Z","closed_at":"2026-06-04T18:31:24Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"jolt-7dy","title":"MED: compiler path lacks IFn dispatch (collections-as-fn) — only interpreter fixed","status":"open","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:10:00Z","created_by":"Yogthos","updated_at":"2026-06-04T18:10:00Z","dependency_count":0,"dependent_count":0,"comment_count":0} -{"_type":"issue","id":"jolt-90c","title":"MED: filter/take-while not lazy — infinite-seq (take N (filter p (range))) loops","status":"open","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:10:00Z","created_by":"Yogthos","updated_at":"2026-06-04T18:10:00Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"jolt-90c","title":"MED: filter/take-while not lazy — infinite-seq (take N (filter p (range))) loops","status":"closed","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:10:00Z","created_by":"Yogthos","updated_at":"2026-06-04T18:56:26Z","closed_at":"2026-06-04T18:56:26Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"jolt-7n5","title":"MED: REPL display — def/defn should print #'ns/name; lazy-seq printer realizes only head ((0 \u003cfunction\u003e))","status":"closed","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:59Z","created_by":"Yogthos","updated_at":"2026-06-04T18:55:11Z","closed_at":"2026-06-04T18:55:11Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"jolt-h0n","title":"MED: missing core fns — letfn fnil trampoline doseq cycle partition-all reductions dedupe keep-indexed map-indexed transduce reduce-kv assoc-in peek subvec read-string format","status":"open","priority":3,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:58Z","created_by":"Yogthos","updated_at":"2026-06-04T18:09:58Z","dependency_count":0,"dependent_count":0,"comment_count":0} diff --git a/src/jolt/core.janet b/src/jolt/core.janet index ad644a1..132b792 100644 --- a/src/jolt/core.janet +++ b/src/jolt/core.janet @@ -434,10 +434,23 @@ (make-lazy-seq (step init-cs init-idxs init-reals))))) (defn core-filter [pred coll] - (var result @[]) - (each x (if (set? coll) (phs-seq coll) (realize-for-iteration coll)) - (if (pred x) (array/push result x))) - (if (tuple? coll) (tuple/slice (tuple ;result)) result)) + (if (lazy-seq? coll) + # lazy input -> lazy output (supports infinite seqs) + (do + (defn fstep [c] + (fn [] + (var cur c) (var hit nil) (var found false) + (while (and (not found) (not (seq-done? cur))) + (let [x (core-first cur)] + (if (pred x) (do (set hit @[x (core-rest cur)]) (set found true)) + (set cur (core-rest cur))))) + (if found @[(in hit 0) (fstep (in hit 1))] nil))) + (make-lazy-seq (fstep coll))) + (do + (var result @[]) + (each x (if (set? coll) (phs-seq coll) coll) + (if (pred x) (array/push result x))) + (if (tuple? coll) (tuple/slice (tuple ;result)) result)))) (defn core-remove [pred coll] (core-filter (fn [x] (not (pred x))) coll)) @@ -497,10 +510,18 @@ (array/slice coll (min n (length coll))))))) (defn core-take-while [pred coll] - (var result @[]) - (each x coll - (if (pred x) (array/push result x) (break))) - (if (tuple? coll) (tuple/slice (tuple ;result)) result)) + (if (lazy-seq? coll) + (do + (var result @[]) (var cur coll) (var go true) + (while (and go (not (seq-done? cur))) + (let [x (core-first cur)] + (if (pred x) (do (array/push result x) (set cur (core-rest cur))) + (set go false)))) + result) + (do + (var result @[]) + (each x coll (if (pred x) (array/push result x) (break))) + (if (tuple? coll) (tuple/slice (tuple ;result)) result)))) (defn core-drop-while [pred coll] (var c (if (lazy-seq? coll) (realize-ls coll) coll)) diff --git a/test/conformance.janet b/test/conformance.janet index 965e14e..9e84a29 100644 --- a/test/conformance.janet +++ b/test/conformance.janet @@ -119,6 +119,12 @@ ["letfn mutual" "true" "(letfn [(ev? [n] (if (= n 0) true (od? (dec n)))) (od? [n] (if (= n 0) false (ev? (dec n))))] (ev? 10))"] ["doseq side" "[1 2 3]" "(do (def a (atom [])) (doseq [x [1 2 3]] (swap! a conj x)) @a)"] ["doseq nested" "4" "(do (def c (atom 0)) (doseq [x [1 2] y [10 20]] (swap! c inc)) @c)"] + + ### ---- MED: lazy filter / take-while over infinite seqs ---- + ["lazy filter inf" "(quote (1 3 5 7 9))" "(take 5 (filter odd? (range)))"] + ["lazy take-while inf" "(quote (0 1 2 3 4))" "(take-while (fn [x] (< x 5)) (range))"] + ["lazy remove inf" "(quote (0 2 4 6 8))" "(take 5 (remove odd? (range)))"] + ["filter finite" "(quote (2 4))" "(filter even? [1 2 3 4 5])"] ]) (var pass 0)