(module loop_recur_1_isqrt_newton
  (fn main
    (doc "Integer square root of 152399025 (= 12345^2) via Newton's method, then a sanity-difference. Expected stdout: 12345 then 0.")
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body
      (let r (app isqrt 152399025)
        (seq (app print r)
             (app print (app - r 12345))))))
  (fn isqrt
    (doc "Newton's method for floor(sqrt(n)). Two binders: x (current guess) and prev (previous guess, to detect the fixpoint/2-cycle). The recur is buried inside a nested if, not at body toplevel.")
    (type (fn-type (params (own (con Int))) (ret (own (con Int)))))
    (params n)
    (body
      (if (app lt n 2)
          n
          (loop (x (con Int) n) (prev (con Int) 0)
            (if (app eq x prev)
                x
                (let next (app / (app + x (app / n x)) 2)
                  (if (app eq next x)
                      next
                      (recur next x)))))))))
