;;;; A number literal bound by let or loop takes its type from its uses in ;;;; the function. Each line's expected output is beside it. ;; A set of an i64 sum makes the accumulator an i64. (defn total [xs [i64]] i64 (let [t 0] (dotimes [i (length xs)] (set t (+ t (at xs i)))) t)) ;; The operand beside it: an f64 accumulator from a float literal. (defn mean [xs [f64]] f64 (let [s 0.0] (dotimes [i (length xs)] (set s (+ s (at xs i)))) (/ s (f64 (length xs))))) ;; A counter compared with an i64 bound counts past i32. (defn count-to [n i64] i64 (let [i 0] (while (< i n) (set i (+ i 1000000000))) i)) ;; A set of one literal local into another links them: b holds a value past ;; i32, so a is an i64 too. (defn linked [] i64 (let [a 0 b 0] (set b 3000000000) (set a b) a)) ;; Two locals fed from each other: i is counted against an i64, and acc ;; sums a literal past i32. (defn sum-to [n i64] i64 (let [i 0 acc 0] (while (< i n) (set acc (+ acc 1000000000)) (set i (+ i 1))) acc)) ;; Inside a generic body the literal takes the type variable. (defn sum-of [xs [$t]] $t {:where (numeric? $t)} (let [acc 0] (dotimes [i (length xs)] (set acc (+ acc (at xs i)))) acc)) ;; A chain of sets settles however long it is. (defn chained [x i64] i64 (let [a0 0 a1 0 a2 0 a3 0 a4 0 a5 0] (set a0 x) (set a1 (+ a0 1)) (set a2 (+ a1 1)) (set a3 (+ a2 1)) (set a4 (+ a3 1)) (set a5 (+ a4 1)) a5)) ;; A dyn number is an i64 or an f64, and so is a literal local it feeds. (defn boxed [x] dyn x) (defn from-dyn [] () (let [d (boxed 0.1) s 0.0 n 0] (set s (+ s d)) (set n (+ n (boxed 5000000000))) (println s n))) (defn main [] i32 (let [xs (the [3 i64] [3000000000 4 5]) fs (the [2 f64] [0.5 0.25]) gs (the [2 u8] [200 50])] (println (total (slice xs 0 3))) ; 3000000009 (println (mean (slice fs 0 2))) ; 0.375 (println (count-to 5000000000)) ; 5000000000 (println (linked)) ; 3000000000 (println (sum-to 3)) ; 3000000000 (println (sum-of (slice xs 0 3))) ; 3000000009 (println (sum-of (slice fs 0 2)))) ; 0.75 (println (chained 3000000000)) ; 3000000005 (from-dyn) ; 0.1 5000000000 (let [x 0.1] (println (= (boxed x) (boxed 0.1)))) ; true ;; Nothing says otherwise: an i32 and an f64. (let [n 7 f 1.5] (println n f)) ; 7 1.5 0)