(module mrb_2_float_smooth
  (fn store_pair
    (doc "Thread a Float RawBuf through an own->own helper that writes two slots and hands the buffer back. Tests threading a buffer through a function under the uniqueness/mode discipline: caller gives up own, callee returns own.")
    (type (fn-type
      (params (own (con RawBuf (con Float))) (own (con Float)) (own (con Float)))
      (ret (own (con RawBuf (con Float))))))
    (params buf a b)
    (body
      (let buf (app RawBuf.set buf 0 a)
        (app RawBuf.set buf 1 b))))
  (fn average
    (doc "Read both slots through a borrow and return their mean. Float element variety: double load + float arithmetic.")
    (type (fn-type
      (params (borrow (con RawBuf (con Float))))
      (ret (own (con Float)))))
    (params buf)
    (body
      (app / (app + (app RawBuf.get buf 0) (app RawBuf.get buf 1)) 2.0)))
  (fn main
    (doc "Allocate a 2-slot Float RawBuf, store 3.0 and 4.0 via the own->own helper, then print their average (3.5).")
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body
      (let buf (new RawBuf (con Float) 2)
        (let buf (app store_pair buf 3.0 4.0)
          (app print (app average buf)))))))
