;;;; [const T]: a slice that can only be read. bytes-view answers one, a [T] ;;;; converts to one wherever one is wanted, and slicing one keeps it ;;;; read-only. Nothing about it exists at run time, so this prints the same ;;;; on every backend and at every level. (defn total [s [const i32]] i64 (let [t (i64 0)] (dotimes [i (length s)] (set t (+ t (at s i)))) t)) ;; A generic over a read-only slice takes a writable one too. (defn first-of [s [const $t]] $t (at s 0)) (defn widths [parts [const [const u8]]] i32 (let [n 0] (dotimes [i (length parts)] (set n (+ n (length (at parts i))))) n)) ;; A (Ptr const T) is what the address of read-only storage is. (defn peek [p (Ptr const u8)] u8 (deref p)) ;; A function that only reads stands where one that may write is wanted, and ;; one returning a writable slice where a read-only one is wanted. (defn rd [s [const u8]] i32 (length s)) (defn call-rd [f (Fn [[u8]] i32)] i32 (f (bytes "abc"))) (defn call-bare [f (CFn [[u8]] i32)] i32 (f (bytes "abcd"))) (defn mk [] [u8] (bytes "xy")) (defn call-mk [f (Fn [] [const u8])] i32 (length (f))) (defn main [] i32 (let [xs [3 1 2] w (slice xs) r (bytes-view "hello, world") head (slice r 0 5) tail (slice r 7) names (vec-new [const u8])] (sort w) (println (total w) (total (slice w 1))) (println (first-of w) (first-of (bytes-view "z"))) (println (string head) (string tail) (length head)) (println (bytes=? head (bytes-view "hello")) (starts-with? r head)) (push names head) (push names tail) (println (widths (slice names))) ;; A writable [[u8]] meets [const [const u8]] too: the outer view is ;; read-only, so nothing can put a read-only slice into it. (let [a (bytes "ab") b (bytes "cde") both [a b]] (println (widths (slice both))) (set (at a 0) \A) (println (string a))) (let [f (split (bytes-view "b,a,c") \,)] (sort-bytes (slice f)) (println (string (slice (join (slice f) (bytes-view "-")))))) (println (at r 0)) (println (call-rd rd) (call-bare rd) (call-mk mk)) (let [b (bytes "q")] (println (peek (addr (at r 1))) (peek (addr (at "abc" 2))) (peek (addr (at b 0))) (string (slice-from (addr (at r 7)) 5)))) (free names)) 0)