swap!, reverse!, sort!, sort-by!, index-of, min-of, max-of, map!, reduce and filter, each written once over $t. Every call site in the corpus moves with them. min-of and max-of are not min and max because min and max are builtins over two or more numbers and nothing shadows a builtin. These reduce a slice, which is a different operation at a different arity. sort-bytes! did not collapse into sort!, and the reason is the point of the predicates: a [u8] is not ordered? and cannot be, because < is an instruction and comparing two slices lexicographically is a loop. It is sort-by! with bytes<? written in, one line, keeping its name and its stability note. sum-i32/sum-f32 and append-i64!/append-f64! stay for the reasons the spike gave. Not what the notes predicted: none of the ten collapses on a signature change alone. filter and reduce need copyable? because the checker demands it - reduce's accumulator at (Vec i32) is a double move - and the rest declare it because a slice of owning elements would have them duplicating headers.
51 lines
2.0 KiB
Plaintext
51 lines
2.0 KiB
Plaintext
;; The prelude's function-taking family: map!, filter, reduce and a comparator
|
|
;; sort. These were the four the second tier could not write, and they arrived
|
|
;; the day function values did — so what this checks is that they are ordinary
|
|
;; prelude functions, called the ordinary way, with the function passed by
|
|
;; name or written inline.
|
|
|
|
(defn triple [x i32] i32 (* x 3))
|
|
(defn odd? [x i32] bool (= (% x 2) 1))
|
|
(defn adds [a i32 b i32] i32 (+ a b))
|
|
(defn longer-first [a i32 b i32] bool (> a b))
|
|
(defn halve [x f32] f32 (/ x 2.0))
|
|
(defn big? [x f32] bool (> x 1.0))
|
|
|
|
(defn main [] i32
|
|
;; map! writes back into the slice it was handed.
|
|
(let [xs [1 2 3 4]
|
|
s (slice xs 0 4)]
|
|
(map! s triple)
|
|
(print (at s 0)) (print " ") (print (at s 3)) (println "")
|
|
|
|
;; reduce, with the accumulator first in the step. The prelude's own
|
|
;; sum-i32 is this with the + written in.
|
|
(print (reduce s 0 adds)) (println "")
|
|
;; ... and an fn literal, whose parameter types come from the parameter.
|
|
(print (reduce s 1 (fn [a b] (* a b)))) (println "")
|
|
|
|
;; filter allocates and the caller frees.
|
|
(let [v (filter s odd?)]
|
|
(print (len v)) (print " ") (print (at v 0)) (println "")
|
|
(free v))
|
|
|
|
;; A comparator sort, both directions off the same slice.
|
|
(sort-by! s longer-first)
|
|
(print (at s 0)) (print " ") (print (at s 3)) (println "")
|
|
(sort-by! s (fn [a b] (< a b)))
|
|
(print (at s 0)) (print " ") (print (at s 3)) (println ""))
|
|
|
|
;; The f32 half of the family, which is the same code at the other element
|
|
;; type — the copy that generics would remove.
|
|
(let [ys [(f32 4.0) (f32 1.0) (f32 8.0) (f32 2.0)]
|
|
t (slice ys 0 4)]
|
|
(map! t halve)
|
|
(print (at t 0)) (print " ") (print (at t 2)) (println "")
|
|
(print (reduce t 0.0 (fn [a b] (+ a b)))) (println "")
|
|
(let [w (filter t big?)]
|
|
(print (len w)) (println "")
|
|
(free w))
|
|
(sort-by! t (fn [a b] (> a b)))
|
|
(print (at t 0)) (print " ") (print (at t 3)) (println ""))
|
|
0)
|