(defsuite "multiple-values" (deftest "values single returns value directly" (do (assert= 42 (values 42)) (assert= "hi" (values "hi")) (assert= nil (values nil)))) (deftest "values multiple returns marker dict" (do (let ((v (values 1 2 3))) (assert (dict? v)) (assert= true (get v :_values false)) (assert-equal (list 1 2 3) (get v :_list))))) (deftest "call-with-values basic two values" (do (assert= 3 (call-with-values (fn () (values 1 2)) (fn (a b) (+ a b)))))) (deftest "call-with-values three values" (do (assert= 6 (call-with-values (fn () (values 1 2 3)) (fn (a b c) (+ a b c)))))) (deftest "call-with-values single value passthrough" (do (assert= 10 (call-with-values (fn () 10) (fn (x) x))))) (deftest "call-with-values passes non-values result as single arg" (do (assert= "hello" (call-with-values (fn () "hello") (fn (x) x))))) (deftest "call-with-values with string concat" (do (assert= "ab" (call-with-values (fn () (values "a" "b")) (fn (a b) (str a b)))))) (deftest "let-values basic two bindings" (do (let-values (((a b) (values 10 20))) (assert= 10 a) (assert= 20 b)))) (deftest "let-values computes with bindings" (do (let-values (((x y) (values 3 4))) (assert= 7 (+ x y))))) (deftest "let-values three values" (do (let-values (((a b c) (values 1 2 3))) (assert= 6 (+ a b c))))) (deftest "let-values single value binding" (do (let-values (((x) (values 42))) (assert= 42 x)))) (deftest "let-values multiple binding clauses" (do (let-values (((a b) (values 1 2)) ((c d) (values 3 4))) (assert= 10 (+ a b c d))))) (deftest "let-values body is multiple expressions" (do (let-values (((a b) (values 5 6))) (define sum (+ a b)) (assert= 11 sum)))) (deftest "let-values with no bindings evals body" (do (let-values () (assert= 99 99)))) (deftest "define-values binds multiple names" (do (define-values (x y) (values 7 8)) (assert= 7 x) (assert= 8 y))) (deftest "define-values three names" (do (define-values (a b c) (values 10 20 30)) (assert= 10 a) (assert= 20 b) (assert= 30 c))) (deftest "define-values single name" (do (define-values (n) (values 42)) (assert= 42 n))) (deftest "define-values used in computation" (do (define-values (w h) (values 6 7)) (assert= 42 (* w h)))) (deftest "values in let binding" (do (let ((v (values 100 200))) (assert= true (get v :_values false)) (assert= 100 (first (get v :_list)))))) (deftest "call-with-values with swap" (do (define (swap a b) (values b a)) (assert= 5 (call-with-values (fn () (swap 3 5)) (fn (first-val second-val) first-val))))) (deftest "let-values from function returning values" (do (define (min-max a b) (values (min a b) (max a b))) (let-values (((lo hi) (min-max 7 3))) (assert= 3 lo) (assert= 7 hi)))) (deftest "nested let-values" (do (let-values (((a b) (values 1 2))) (let-values (((c d) (values 3 4))) (assert= 10 (+ a b c d)))))) (deftest "call-with-values chained" (do (define result (call-with-values (fn () (call-with-values (fn () (values 4 6)) (fn (a b) (* a b)))) (fn (x) x))) (assert= 24 result))) (deftest "values zero args produces dict" (do (let ((v (values))) (assert (dict? v)) (assert (get v :_values false)) (assert-equal (list) (get v :_list))))) (deftest "let-values strings" (do (let-values (((first-name last-name) (values "Alice" "Smith"))) (assert= "Alice Smith" (str first-name " " last-name))))) (deftest "define-values with list values" (do (define-values (head tail) (values 1 (list 2 3 4))) (assert= 1 head) (assert-equal (list 2 3 4) tail))))