;;;; (slice-from-ptr p n) — NEXT.md, "a pointer from C needs a length before it ;;;; can be indexed". The motivating pointers come from C, but nothing about ;;;; the form does: a (Ptr T) is a (Ptr T) whoever made it, so this case makes ;;;; its own with (addr (at a 0)) and needs no library and no window. ;;;; ;;;; What is asserted, line by line: ;;;; ;;;; - the length is the one the caller stated, and (len s) answers it; ;;;; - the elements read through are the same storage, not a copy — the last ;;;; two lines write through the slice and read the array back, which is ;;;; the whole ptr+len claim; ;;;; - a shorter promise than the truth is legal and is what indexing then ;;;; believes, because the caller's number is the only length there is; ;;;; - the result is an ordinary [T]: it slices, it is passed to a function ;;;; that takes a slice, and the prelude's algorithms work on it. ;;;; ;;;; What is NOT here, and is in test_flan.ml's refusal table instead: a ;;;; negative literal length, a first argument that is not a pointer, and ;;;; (free (slice-from-ptr ...)) — a slice owns nothing, so free refuses it by ;;;; the rule it already had. (defvar a [5 i32]) (defn total [s [i32]] i32 (let [acc 0] (dotimes [i (len s)] (set acc (+ acc (at s i)))) acc)) (defn main [] () (dotimes [i 5] (set (at a i) (* (+ i 1) 10))) ;; The whole array, as the caller promises it: five elements behind the ;; address of the first. (let [s (slice-from-ptr (addr (at a 0)) 5)] (println (len s)) ; 5 (println (at s 0)) ; 10 (println (at s 4)) ; 50 (println (total s)) ; 150 ;; An ordinary [i32] from here on: slice it, and the sub-view still points ;; into the same storage. (println (total (slice s 1 3)))) ; 50 ;; A promise shorter than the truth. Nothing complains — there is nothing to ;; complain with — and the length the caller gave is the length indexing and ;; the bounds check both use. (let [s (slice-from-ptr (addr (at a 1)) 2)] (println (len s)) ; 2 (println (total s))) ; 50 ;; Zero is a length like any other. An empty slice is not a null pointer and ;; is not an error. (println (len (slice-from-ptr (addr (at a 0)) 0))) ; 0 ;; It is a view, not a copy: a write through the slice is a write to the ;; array, and this is what would fail if the form ever grew a memcpy. (let [s (slice-from-ptr (addr (at a 0)) 5)] (set (at s 2) 7) (println (at a 2)) ; 7 (println (total s)))) ; 127