;;;; A Vec reached through a [const (Vec T)] or a (Ptr const (Vec T)) is used ;;;; where it stands — indexed, measured, sliced, its address taken — and never ;;;; copied out as a value; (clone v) is the copy. The refusals are in ;;;; test_flan.ml; this is the half that compiles, on both backends. (defstruct Bag [items (Vec i32) n i32]) (defn total [vs [const (Vec i32)]] i32 (let [t 0] (dotimes [i (length vs)] (dotimes [j (length (at vs i))] (set t (+ t (at (at vs i) j))))) t)) (defn first-len [p (Ptr const (Vec i32))] i32 (length (deref p))) (defn bag-n [bs [const Bag]] i32 (+ (.n (at bs 0)) (length (.items (at bs 0))))) (defn pick [c bool a $t b $t] $t (if c a b)) (defn main [] i32 (let [a (vec-new i32) b (vec-new i32)] (push a 1) (push a 2) (push b 30) (let [vs [a b] cv (the-const (slice vs)) w (clone (at cv 0)) bags [(Bag {.items b .n 4})]] (push w 99) ;; The shallow rule: the Vec's own buffer is writable through the view. (set (at (at cv 1) 0) 31) (println (total cv) (length w) (length (at cv 0))) (println (first-len (addr (at cv 0))) (bag-n (slice bags))) (println (length (pick true (bytes-view "abc") (bytes "de"))) (length (pick false (bytes "de") (bytes-view "abc")))))) 0) (defn the-const [s [const (Vec i32)]] [const (Vec i32)] s)