S-exp GPU
All pages
Docs · The languageMarkdown

Truth, iteration and values

Truth and staging

nil and false are false; every other ordinary value is true, including zero, the empty string and an empty vector. if, when, unless, cond, and, or, not, truthy, filter and assert all use this rule. and and or return the deciding value itself, not a boolean.

A tensor, a parameter or a ctx scalar used as a condition is E-FLOW-001. Shapes are static and both branches must exist in the graph, so select elementwise instead:

(if (> x 0.0) x 0.0)              ; E-FLOW-001: x is a tensor
(where (> x 0.0) x (zeros-like x)) ; the graph computes both, picks per element
(if (> (dim x 0) (dim x 1)) ...)  ; fine: dim is an ordinary integer

Shape queries (shape, rank, dim, numel, dtype) return ordinary values, so compile-time decisions on shapes are plain ifs. That is how Muon transposes a tall matrix; see sexpgpu/optim.

Iteration

formbehavior
(dotimes (i count [result]) body...)evaluates count once, runs the body for i from 0 below it; a negative count runs nothing; result sees i equal to the iteration count
(dolist (item list [result]) body...)evaluates the list once, runs the body per element; result sees item bound to nil
(repeat n f)calls f with 0..n-1 and collects the results: how a stack of blocks is built
(map f xs), (filter f xs), (reduce f init xs)collecting and folding; see builtins

dotimes and dolist collect nothing: they return result, or nil without one, and preserve its multiple values. Their loop variable is one binding shared across iterations. With a tensor accumulator they unroll into the graph:

(let ((result (zeros-like x)))
  (dotimes (i degree result)
    (setq result (+ result (* (sum (slice coefficients 0 i (+ i 1))) (pow x i))))))

Multiple values

(values expr...) returns zero or more values. Ordinary arguments, variable initializers, assignments, vector elements and training contract components take the primary value; zero values give nil there. The last form of a body and the chosen branch of if keep all values.

formbehavior
(values-list list)the list's elements as values
(multiple-value-list expr)all returned values as a list
(multiple-value-bind (names...) expr body...)binds the values; missing ones are nil, extras discarded
(multiple-value-call f expr...)calls f with every value of every expr, concatenated
(multiple-value-prog1 expr body...)returns expr's values after running the body

sexpgpu eval prints several values as #<values ...>.

Errors on purpose

  • (error message...) stops compilation with E-EVAL-001 and the message.
  • (assert test [message]) stops with E-EVAL-002 when test is false: (assert (= 2 (rank param)) "muon updates matrices").

Both point at the line that raised them, or at your model application when raised inside a library. See check.

Related: It is Common Lisp, tensor operations.