; Axis: conditional classification an imperative author writes as
; "set a code variable through a cascade of if-branches".
;
; Imperative instinct (the shape `mut` would invite):
;   g = 0           ; 0=F
;   if score >= 60: g = 1   ; D
;   if score >= 70: g = 2   ; C
;   if score >= 80: g = 3   ; B
;   if score >= 90: g = 4   ; A
;   return g
;
; Surviving-surface shape: either a let-threaded `g` updated by
; nested `if`, or a single nested `if` cascade. Both are pure
; expressions; the `mut` flag was never needed.
; grade(95)=4 (A), grade(72)=2 (C), grade(50)=0 (F).
; Expected stdout (per line): 4, 2, 0

(module remove-mut_2_grade_cascade

  (fn grade
    (doc "Letter-grade code (4=A..0=F) from a numeric score, written as the let-threaded equivalent of a mutable cascade.")
    (type (fn-type (params (own (con Int))) (ret (own (con Int)))))
    (params score)
    (body
      (let g 0
        (let g (if (app ge score 60) 1 g)
          (let g (if (app ge score 70) 2 g)
            (let g (if (app ge score 80) 3 g)
              (let g (if (app ge score 90) 4 g)
                g)))))))

  (fn main
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body
      (seq (app print (app grade 95))
      (seq (app print (app grade 72))
           (app print (app grade 50)))))))
