haskell: seq + deepseq via lazy-builtin flag (+9 tests, 368/368)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled

This commit is contained in:
2026-04-25 00:28:19 +00:00
parent cc5315a5e6
commit 04a25d17d0
3 changed files with 139 additions and 7 deletions

View File

@@ -87,7 +87,17 @@
hk-mk-builtin
(fn
(name fn arity)
{:type "builtin" :name name :fn fn :arity arity :collected (list)}))
{:type "builtin" :name name :fn fn :arity arity :lazy false :collected (list)}))
;; A lazy built-in receives its collected args as raw thunks (or
;; values, if those happened to be eager) — the implementation is
;; responsible for forcing exactly what it needs. Used for `seq`
;; and `deepseq`, which are non-strict in their second argument.
(define
hk-mk-lazy-builtin
(fn
(name fn arity)
{:type "builtin" :name name :fn fn :arity arity :lazy true :collected (list)}))
;; ── Apply a function value to one argument ──────────────────
(define
@@ -199,11 +209,15 @@
((< (len collected) arity)
(assoc b "collected" collected))
(:else
;; Built-ins are strict in all their arguments. Force each
;; collected thunk before invoking the underlying SX fn.
(apply
(get b "fn")
(map hk-force collected)))))))
;; Strict built-ins force every collected arg before
;; calling. Lazy ones (`seq`, `deepseq`) receive the raw
;; thunks so they can choose what to force.
(cond
((get b "lazy") (apply (get b "fn") collected))
(:else
(apply
(get b "fn")
(map hk-force collected)))))))))
;; ── Bool helpers (Bool values are tagged conses) ────────────
(define
@@ -583,6 +597,23 @@ plus a b = a + b
env
"id"
(hk-mk-builtin "id" (fn (x) x) 1))
;; `seq a b` — strict in `a`, lazy in `b`. Forces `a` to WHNF
;; and returns `b` unchanged (still a thunk if it was one).
(dict-set!
env
"seq"
(hk-mk-lazy-builtin
"seq"
(fn (a b) (do (hk-force a) b))
2))
;; `deepseq a b` — like seq but forces `a` to normal form.
(dict-set!
env
"deepseq"
(hk-mk-lazy-builtin
"deepseq"
(fn (a b) (do (hk-deep-force a) b))
2))
;; Operators as first-class values
(dict-set! env "+" (hk-make-binop-builtin "+" "+"))
(dict-set! env "-" (hk-make-binop-builtin "-" "-"))