flan/test/programs/literal-locals.flan

60 lines
1.9 KiB
Plaintext

;;;; 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))
;; recur rebinds a loop's names the way set does.
(defn sum-to [n i64] i64
(loop [i 0 acc 0]
(if (< i n) (recur (+ i 1) (+ acc 1000000000)) 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))
(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
;; Nothing says otherwise: an i32 and an f64.
(let [n 7 f 1.5]
(println n f)) ; 7 1.5
0)