;; map-keys and map-values: the prelude's two generic walks over a map. Block ;; order is the hash's, so what comes back is sorted before it is printed. ;; ;; The three globals are named after the prelude's type variables. A generic's ;; body names its element type as $t, $k or $v, never bare, because a bare ;; name there is an expression and would find these. (defonce t i32 0) (defonce k i32 0) (defonce v i32 0) (defn adder [n i32] (Fn [i32] i32) (fn [x] (+ x n))) (defn main [] i32 (let [m (map-new i32 i64)] (put m 30 (i64 300)) (put m 10 (i64 100)) (put m 20 (i64 200)) (let [ks (map-keys m) vs (map-values m)] (sort (slice ks)) (sort (slice vs)) (dotimes [i (length ks)] (print (at ks i)) (print " ")) (println "") (dotimes [i (length vs)] (print (at vs i)) (print " ")) (println "") (free ks) (free vs)) (free m)) ;; A string key, and a map that never allocated. (let [names (map-new str i32) none (map-new str i32)] (put names "b" 2) (put names "a" 1) (let [ks (map-keys names) nk (map-keys none) total 0] (dotimes [i (length ks)] (set total (+ total (or-else (get names (at ks i)) 0)))) (println total) (println (length nk)) (free ks) (free nk)) (free names) (free none)) ;; Closures as the values: a function value cannot be zeroed, so the walk ;; must not need a place for one. (let [fs (map-new i32 (Fn [i32] i32))] (put fs 1 (adder 1)) (put fs 2 (adder 2)) (let [ks (map-keys fs) vs (map-values fs) total 0] (dotimes [i (length vs)] (set total (+ total ((at vs i) 10)))) (println (length ks)) (println total) (free ks) (free vs)) (free fs)) 0)