(module mut

  (fn mut_empty
    (doc "Empty block; body is a single Int literal.")
    (type (fn-type (params) (ret (own (con Int)))))
    (params)
    (body 0))

  (fn mut_single_var
    (doc "let-rebind: x starts at 0, the block value is x + 1.")
    (type (fn-type (params) (ret (own (con Int)))))
    (params)
    (body (let x 0 (let x (app + x 1) x))))

  (fn mut_two_vars
    (doc "Two let-threaded scalars combined into the block value.")
    (type (fn-type (params) (ret (own (con Float)))))
    (params)
    (body (let sum 0.0 (let count 0 (let sum (app + sum 1.0) (let count (app + count 1) (app + sum (app int_to_float count))))))))

  (fn mut_nested_shadow
    (doc "Nested let shadowing; inner binding is the block value.")
    (type (fn-type (params) (ret (own (con Int)))))
    (params)
    (body (let x 10 (let x (app + x 1) (let x 100 (let x (app + x 1) x))))))

  (fn mut_returns_bool
    (doc "Bool scalar threaded through let; block value is the latest binding.")
    (type (fn-type (params) (ret (own (con Bool)))))
    (params)
    (body (let flag false (let flag true flag))))

  (fn mut_returns_unit
    (doc "Unit scalar threaded through let; block value is the latest binding.")
    (type (fn-type (params) (ret (own (con Unit)))))
    (params)
    (body (let u (lit-unit) (let u (lit-unit) u)))))
