feat: clojure.core.async on Janet fibers (Phase 1 — API layer)
Janet fibers are stackful coroutines, so a go block is just its body run in a fiber that parks on channel ops by yielding to the event loop — the interpreter call stack rides along, no CPS/state-machine transform. So <!/>! work anywhere (inside try, nested fns, loops), unlike Clojure's go macro. src/jolt/async.janet implements chan/chan?/close!/<!/>!/<!!/>!!/go/go-loop/ thread/alts!/timeout/put!/take! over ev/ channels and fibers, installed as the clojure.core.async namespace (pre-populated in init, so require finds it). A channel is a pair of ev/chans (:ch values + :done close-signal); a take is (ev/select :ch :done), which drains buffered values before the close signal — giving Clojure's drain-then-nil semantics without the buffer loss of ev/chan-close, and with no leaked fibers (close! just closes :done). Single-threaded cooperative scheduling: <! (park) and <!! (block) coincide. Dynamic-var conveyance (Phase 2) and channel transducers (Phase 3) are TODO. spec: test/spec/core-async-spec (16 cases — go/channels, buffering+close, go-loop pipelines, alts!/timeout, parking inside try/nested-fn). jpm test green.
This commit is contained in:
parent
858c7fed14
commit
7d1e1f42e1
7 changed files with 212 additions and 0 deletions
|
|
@ -5,6 +5,8 @@
|
|||
{"_type":"issue","id":"jolt-x8s","title":"CRITICAL: collections not callable as IFn (vector/map/set)","status":"closed","priority":1,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T17:46:14Z","created_by":"Yogthos","updated_at":"2026-06-04T17:50:54Z","closed_at":"2026-06-04T17:50:54Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-alz","title":"CRITICAL: self-referential lazy-seq/lazy-cat yields only literal prefix","status":"closed","priority":1,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T17:46:13Z","created_by":"Yogthos","updated_at":"2026-06-04T18:09:15Z","closed_at":"2026-06-04T18:09:15Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-wec","title":"CRITICAL: multi-collection map returns unrealized thunk","status":"closed","priority":1,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T17:46:12Z","created_by":"Yogthos","updated_at":"2026-06-04T18:06:02Z","closed_at":"2026-06-04T18:06:02Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-5i5","title":"core.async Phase 2: dynamic var binding conveyance","description":"Snapshot/restore the global binding-stack per fiber so dynamic var bindings don't interleave across concurrent go blocks (Clojure binding conveyance).","status":"open","priority":2,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-05T18:55:08Z","created_by":"Yogthos","updated_at":"2026-06-05T18:55:08Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-tkw","title":"core.async on Janet fibers — Phase 1: API layer","description":"Implement clojure.core.async API (chan/go/\u003c!/\u003e!/\u003c!!/\u003e!!/close!/alts!/timeout/put!/take!/buffers) on top of Janet ev/ channels and fibers. go = run body in a fiber (stackful, no CPS macro needed).","status":"open","priority":2,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-05T18:55:07Z","created_by":"Yogthos","updated_at":"2026-06-05T18:55:07Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-lko","title":"clojure-test-suite: strictness — throw on malformed calls like Clojure","description":"Make jolt throw where Clojure throws (bad-shape conj!/assoc!, arithmetic on non-numbers, out-of-range indices, etc.) to satisfy the suite's ~292 p/thrown? assertions. Targeted input validation across affected fns; guard against regressing jolt's spec/conformance.","status":"closed","priority":2,"issue_type":"task","assignee":"Yogthos","owner":"yogthos@gmail.com","created_at":"2026-06-05T14:45:20Z","created_by":"Yogthos","updated_at":"2026-06-05T18:07:56Z","started_at":"2026-06-05T14:45:39Z","closed_at":"2026-06-05T18:07:56Z","close_reason":"Implemented Clojure-strict argument validation across ~30 fns; suite pass 3691-\u003e3898, p/thrown? bucket 292-\u003e~60 (remainder is platform: int 32-bit range, subs Unicode, min-key NaN, subvec floats, map-entry-as-2-vector)","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-kxb","title":"clojure-test-suite: transducers don't short-circuit over infinite seqs (hangs)","description":"(into [] (take 5) (range)) and similar transducer-over-infinite forms hang jolt's eager evaluator (no reduced/early-termination). 7 suite files time out. Make transducing honor reduced.","status":"closed","priority":2,"issue_type":"bug","assignee":"Yogthos","owner":"yogthos@gmail.com","created_at":"2026-06-05T13:05:18Z","created_by":"Yogthos","updated_at":"2026-06-05T13:18:37Z","started_at":"2026-06-05T13:09:59Z","closed_at":"2026-06-05T13:18:37Z","close_reason":"reduce-with-reduced steps lazy seqs incrementally; transducers short-circuit over infinite seqs","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-js6","title":"Port clojure-test-suite as integration battery","description":"Build a minimal clojure.test + portability shim so Jolt can load the external ~/src/clojure-test-suite (240 per-fn .cljc files in clojure.test format). Add a baseline-guarded integration runner following the jank-conformance pattern (skip if absent).","status":"closed","priority":2,"issue_type":"task","assignee":"Yogthos","owner":"yogthos@gmail.com","created_at":"2026-06-05T12:22:01Z","created_by":"Yogthos","updated_at":"2026-06-05T13:05:04Z","started_at":"2026-06-05T12:22:14Z","closed_at":"2026-06-05T13:05:04Z","close_reason":"Ported clojure-test-suite as baseline-guarded integration battery; surfaced+fixed 2 evaluator macro bugs","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
|
|
@ -15,6 +17,7 @@
|
|||
{"_type":"issue","id":"jolt-40n","title":"HIGH: update/update-in/assoc-in fail on map literals (struct)","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:40:42Z","closed_at":"2026-06-04T18:40:42Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_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-x3v","title":"core.async Phase 3: channel transducers","description":"Support (chan n xform) — apply a transducer to values flowing through a channel, plus dropping/sliding buffers.","status":"open","priority":3,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-05T18:55:09Z","created_by":"Yogthos","updated_at":"2026-06-05T18:55:09Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-dxx","title":"clojure-test-suite: merge nil/empty + collection-key semantics","description":"merge.cljc has 18 fail / 11 err — highest in suite. Investigate nil/empty-map merge return values and collection-key behavior.","status":"closed","priority":3,"issue_type":"bug","assignee":"Yogthos","owner":"yogthos@gmail.com","created_at":"2026-06-05T13:05:17Z","created_by":"Yogthos","updated_at":"2026-06-05T13:22:29Z","started_at":"2026-06-05T13:18:50Z","closed_at":"2026-06-05T13:22:29Z","close_reason":"merge follows Clojure (when some identity) (reduce conj ...) semantics; nil/empty/conj-entry cases fixed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-1uw","title":"clojure-test-suite: transient strictness gaps","description":"Transient ops (conj!/assoc!/disj!/pop!) don't throw on misuse (bad shapes, use-after-persistent!) where Clojure does. Surfaced by conj_bang/assoc_bang/pop_bang/persistent_bang/transient suite files (~50 fails). Lenient behavior; decide whether to enforce.","status":"closed","priority":3,"issue_type":"bug","assignee":"Yogthos","owner":"yogthos@gmail.com","created_at":"2026-06-05T13:05:16Z","created_by":"Yogthos","updated_at":"2026-06-05T13:29:38Z","started_at":"2026-06-05T13:22:51Z","closed_at":"2026-06-05T13:29:38Z","close_reason":"Fixed real gaps: invokable transients, assoc! odd args, use-after-persistent! invalidation, pop!-empty. Bad-shape type strictness left as accepted lenient divergence.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-do7","title":"phm-typed maps as set elements / map keys hash by identity","description":"A map produced via hash-map/assoc (a Janet table/phm) used as a set element or map key hashes by identity, so #{{:a 1}} (struct elem) != #{(hash-map :a 1)} (phm elem) and such elements aren't retrievable by value. Map literals (structs) work. Needs value-based hashing for phm keys in PHM/PHS. Edge case; spec covers literal-map cases.","status":"closed","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-05T04:07:50Z","created_by":"Yogthos","updated_at":"2026-06-05T05:02:01Z","closed_at":"2026-06-05T05:02:01Z","close_reason":"Fixed: PHM/PHS canonicalize collection keys for value-based hashing/comparison; map literals \u0026 assoc promote to phm on collection keys; frequencies/group-by use phm base; set = is value-based. Also fixed set literals not evaluating elements and the REPL phm printer. Spec cases added. (commit pushed next)","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue