; Iter 16b.1 — first consumer of (let-rec ...). A single-fn helper
; `fact` is bound by a local recursive let inside `main`'s body and
; called at three different inputs. The desugarer lifts `fact` to a
; synthetic top-level fn (because the body has no captures from
; `main`'s scope) and substitutes the references. The lifted fn is
; type-checked and codegen'd identically to a hand-written
; top-level def. Output (per line): 1, 6, 120.

(module local_rec_demo

  (fn main
    (doc "Iter 16b.1: drive a let-rec'd factorial helper at three inputs. Expected stdout (per line): 1, 6, 120.")
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body
      (let-rec fact
        (params n)
        (type (fn-type (params (own (con Int))) (ret (own (con Int)))))
        (body
          (if (app le n 1)
            1
            (app * n (app fact (app - n 1)))))
        (in
          (seq (seq (app print (app fact 1)) (do io/print_str "\n"))
          (seq (seq (app print (app fact 3)) (do io/print_str "\n"))
               (seq (app print (app fact 5)) (do io/print_str "\n")))))))))
