;; Evaluation rules — machine-readable SX semantics reference. ;; ;; Each rule describes one dispatch case in the CEK evaluator. ;; Rules are data — queried by tools (sx_explain), validated against behavior. ;; Examples are strings to avoid evaluation: "expr → result" (define eval-rules (list {:name "number" :category "literal" :pattern "42" :rule "Numbers evaluate to themselves." :effects () :examples "42 → 42, -3.14 → -3.14"} {:name "string" :category "literal" :pattern "\"hello\"" :rule "Strings evaluate to themselves." :effects () :examples "\"hello\" → \"hello\""} {:name "boolean" :category "literal" :pattern "true | false" :rule "Booleans evaluate to themselves." :effects () :examples "true → true, false → false"} {:name "nil" :category "literal" :pattern "nil" :rule "Nil evaluates to itself. Nil is falsy." :effects () :examples "nil → nil"} {:name "keyword" :category "literal" :pattern ":name" :rule "Keywords evaluate to their string name." :effects () :examples ":foo → \"foo\", :class → \"class\""} {:name "dict" :category "literal" :pattern "{:key1 val1 :key2 val2 ...}" :rule "Create a dictionary. Keys are keywords (evaluated to strings). Values are evaluated." :effects () :examples "{:x 1 :y 2} → {\"x\" 1 \"y\" 2}"} {:name "symbol" :category "lookup" :pattern "name" :rule "Look up in: (1) environment chain, (2) primitives, (3) true/false/nil literals. Error if not found." :effects () :examples "+ → , undefined → ERROR"} {:name "if" :category "special-form" :pattern "(if test then else?)" :rule "Evaluate test. If truthy (not false, not nil), evaluate then. Otherwise evaluate else (or nil if absent). Both branches are in tail position." :effects () :examples "(if true 1 2) → 1, (if false 1 2) → 2, (if nil 1) → nil"} {:name "when" :category "special-form" :pattern "(when test body ...)" :rule "Evaluate test. If truthy, evaluate body forms in sequence, return last. If falsy, return nil. Last body form is in tail position." :effects () :examples "(when true 1 2 3) → 3, (when false 1) → nil"} {:name "cond" :category "special-form" :pattern "(cond test1 expr1 test2 expr2 ... :else default)" :rule "Evaluate tests in order. First truthy test: evaluate and return its expr. :else always matches. If no match, return nil." :effects () :examples "(cond false 1 true 2) → 2, (cond false 1 :else 3) → 3"} {:name "case" :category "special-form" :pattern "(case expr val1 result1 val2 result2 ... :else default)" :rule "Evaluate expr once. Compare against each val (by equality). Return the matched result. :else is the fallback." :effects () :examples "(case 2 1 \"one\" 2 \"two\") → \"two\""} {:name "and" :category "special-form" :pattern "(and expr ...)" :rule "Evaluate left to right. Return first falsy value, or last value if all truthy. Short-circuits." :effects () :examples "(and 1 2 3) → 3, (and 1 false 3) → false"} {:name "or" :category "special-form" :pattern "(or expr ...)" :rule "Evaluate left to right. Return first truthy value, or last value if all falsy. Short-circuits." :effects () :examples "(or false 2 3) → 2, (or false nil) → nil"} {:name "let" :category "special-form" :pattern "(let ((name val) ...) body ...)" :rule "Create new scope. Evaluate each val sequentially, bind name. Then evaluate body forms, return last. Values see only earlier bindings. Last body form is in tail position." :effects () :examples "(let ((x 1) (y 2)) (+ x y)) → 3"} {:name "letrec" :category "special-form" :pattern "(letrec ((name val) ...) body ...)" :rule "Like let, but all bindings are visible to all vals (mutual recursion). Bindings exist before vals are evaluated." :effects () :examples "(letrec ((f (fn (n) (if (= n 0) 1 (* n (f (- n 1))))))) (f 5)) → 120"} {:name "lambda" :category "special-form" :pattern "(fn (params ...) body ...) | (lambda (params ...) body ...)" :rule "Create a closure capturing the current environment. Parameters support: positional, &key (keyword args), &rest (variadic), (:as type) annotations. Last body form is in tail position." :effects () :examples "(fn (x) (+ x 1)) → "} {:name "define" :category "special-form" :pattern "(define name value) | (define name :effects (e ...) value)" :rule "Evaluate value, bind name in the current environment. Optional :effects annotation declares side effects. Returns the value." :effects () :examples "(define x 42) → 42"} {:name "set!" :category "special-form" :pattern "(set! name value)" :rule "Evaluate value, mutate existing binding of name. Walks the scope chain to find the binding. Error if name is not bound." :effects "mutation" :examples "(let ((x 1)) (set! x 2) x) → 2"} {:name "begin" :category "special-form" :pattern "(begin expr ...) | (do expr ...)" :rule "Evaluate expressions in sequence, return last. Last form is in tail position." :effects () :examples "(begin 1 2 3) → 3"} {:name "quote" :category "special-form" :pattern "(quote expr)" :rule "Return expr unevaluated." :effects () :examples "(quote (+ 1 2)) → (+ 1 2)"} {:name "quasiquote" :category "special-form" :pattern "`expr with ,x and ,@xs" :rule "Like quote, but (unquote x) evaluates x, and (splice-unquote x) splices a list." :effects () :examples "(let ((x 1)) `(a ,x b)) → (a 1 b)"} {:name "thread-first" :category "special-form" :pattern "(-> val (fn1 args...) (fn2 args...) ...)" :rule "Thread val through forms. Each form receives the previous result as its first argument. (-> x (f a)) becomes (f x a)." :effects () :examples "(-> 1 (+ 2) (* 3)) → 9"} {:name "defcomp" :category "definition" :pattern "(defcomp ~name (params ...) body ...)" :rule "Define a component. Keyword args via &key, variadic via &rest. Body evaluated in merged env (closure + caller-env + params)." :effects () :examples "(defcomp ~card (&key title) (div (h2 title)))"} {:name "defisland" :category "definition" :pattern "(defisland ~name (params ...) body ...)" :rule "Define an island — a component that hydrates on the client. Server renders a placeholder; client evaluates the body with reactive capabilities." :effects () :examples "(defisland ~counter () (let ((n (signal 0))) (button :on-click (fn (e) (swap! n inc)) (deref n))))"} {:name "defmacro" :category "definition" :pattern "(defmacro name (params ...) body ...)" :rule "Define a macro. At call time, args are passed unevaluated. Body produces a new expression which is then evaluated." :effects () :examples "(defmacro unless (test body) `(if (not ,test) ,body))"} {:name "map" :category "higher-order" :pattern "(map fn coll) | (map coll fn)" :rule "Apply fn to each element of coll, return new list. Argument order is flexible." :effects () :examples "(map (fn (x) (* x 2)) (list 1 2 3)) → (2 4 6)"} {:name "filter" :category "higher-order" :pattern "(filter fn coll) | (filter coll fn)" :rule "Return elements of coll where fn returns truthy. Flexible argument order." :effects () :examples "(filter (fn (x) (> x 2)) (list 1 2 3 4)) → (3 4)"} {:name "reduce" :category "higher-order" :pattern "(reduce fn init coll)" :rule "Fold coll from left. Call (fn acc item) for each element, starting with init." :effects () :examples "(reduce + 0 (list 1 2 3)) → 6"} {:name "some" :category "higher-order" :pattern "(some fn coll)" :rule "Return first truthy result of (fn item), or false if none." :effects () :examples "(some (fn (x) (> x 2)) (list 1 2 3)) → true"} {:name "every?" :category "higher-order" :pattern "(every? fn coll)" :rule "Return true if (fn item) is truthy for all items." :effects () :examples "(every? (fn (x) (> x 0)) (list 1 2 3)) → true"} {:name "for-each" :category "higher-order" :pattern "(for-each fn coll)" :rule "Call (fn item) for each element. Returns nil. Used for side effects." :effects "mutation" :examples "(for-each print (list 1 2 3)) → nil (prints 1, 2, 3)"} {:name "scope" :category "scope" :pattern "(scope name body ...)" :rule "Create a named dynamic scope. The unified primitive beneath provide, collect!, and spreads." :effects "mutation" :examples "(scope \"my-scope\" (emit! \"my-scope\" 42) (emitted \"my-scope\")) → (42)"} {:name "provide" :category "scope" :pattern "(provide name value body ...)" :rule "Make value available to descendants via (context name)." :effects "mutation" :examples "(provide \"theme\" \"dark\" (context \"theme\")) → \"dark\""} {:name "context" :category "scope" :pattern "(context name)" :rule "Retrieve the value from the nearest enclosing (provide name value ...)." :effects () :examples "(provide \"x\" 42 (context \"x\")) → 42"} {:name "emit!" :category "scope" :pattern "(emit! name value)" :rule "Emit a value upward into a named scope." :effects "mutation" :examples "see scope example"} {:name "emitted" :category "scope" :pattern "(emitted name)" :rule "Collect all values emitted into the named scope." :effects () :examples "see scope example"} {:name "reset" :category "continuation" :pattern "(reset body ...)" :rule "Delimit a continuation. shift inside body captures up to this point." :effects () :examples "(reset (+ 1 (shift k (k 10)))) → 11"} {:name "shift" :category "continuation" :pattern "(shift k body ...)" :rule "Capture the continuation up to the nearest reset. k is a function that resumes the captured computation." :effects () :examples "(reset (+ 1 (shift k (k (k 10))))) → 12"} {:name "deref" :category "reactive" :pattern "(deref signal)" :rule "Read the current value of a reactive signal. In a reactive context, establishes a dependency." :effects () :examples "(let ((s (signal 42))) (deref s)) → 42"} {:name "function-call" :category "call" :pattern "(f arg1 arg2 ...)" :rule "Evaluate f and all args left to right. Then: native → apply, lambda → bind params + TCO, component → parse kwargs + bind params + TCO, macro → expand unevaluated args + re-eval." :effects () :examples "(+ 1 2) → 3, (list 1 2 3) → (1 2 3)"} )) ;; Lookup helpers (define find-rule (fn (name) (some (fn (rule) (when (= (get rule "name") name) rule)) eval-rules))) (define rules-by-category (fn (category) (filter (fn (rule) (= (get rule "category") category)) eval-rules))) (define rule-categories (fn () (let ((seen (dict)) (result (list))) (for-each (fn (rule) (let ((cat (get rule "category"))) (when (not (has-key? seen cat)) (dict-set! seen cat true) (append! result cat)))) eval-rules) result)))