spec: sets (make-set/set-add!/set-member?/union/intersection/etc)

Adds 13 set primitives to stdlib.sets. OCaml: SxSet as (string,value)
Hashtbl keyed by inspect(val); JS: SxSet wrapping Map keyed by
write-to-string. Structural equality — (make-set '(1 2)) contains 1.
Includes union, intersection, difference, for-each, map.
33 tests in test-sets.sx, all pass on both JS and OCaml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-01 18:45:46 +00:00
parent 24d78464d8
commit 3b0ac67a10
6 changed files with 478 additions and 2 deletions

View File

@@ -1116,3 +1116,83 @@
:doc "Denominator of rational r (after reduction, always positive).")
(define-module :stdlib.hash-table)
(define-module :stdlib.sets)
(define-primitive
"make-set"
:params (&rest (lst :as list))
:returns "set"
:doc "Create a fresh empty set. Optional list argument seeds the set: (make-set '(1 2 3)).")
(define-primitive
"set?"
:params (v)
:returns "boolean"
:doc "True if v is a set.")
(define-primitive
"set-add!"
:params (s val)
:returns "nil"
:doc "Add val to set s in place. No-op if already present.")
(define-primitive
"set-member?"
:params (s val)
:returns "boolean"
:doc "True if val is in set s.")
(define-primitive
"set-remove!"
:params (s val)
:returns "nil"
:doc "Remove val from set s in place. No-op if absent.")
(define-primitive
"set-size"
:params (s)
:returns "integer"
:doc "Number of elements in set s.")
(define-primitive
"set->list"
:params (s)
:returns "list"
:doc "All elements of set s as a list (unspecified order).")
(define-primitive
"list->set"
:params (lst)
:returns "set"
:doc "Create a new set containing all elements of lst.")
(define-primitive
"set-union"
:params (s1 s2)
:returns "set"
:doc "New set with all elements from s1 and s2.")
(define-primitive
"set-intersection"
:params (s1 s2)
:returns "set"
:doc "New set with elements present in both s1 and s2.")
(define-primitive
"set-difference"
:params (s1 s2)
:returns "set"
:doc "New set with elements in s1 that are not in s2.")
(define-primitive
"set-for-each"
:params (s fn)
:returns "nil"
:doc "Call (fn val) for each element in set s. Order unspecified.")
(define-primitive
"set-map"
:params (s fn)
:returns "set"
:doc "New set of results of (fn val) for each element in s.")