; APL idiom corpus — classic Roger Hui / Phil Last idioms expressed ; through our runtime primitives. Each test names the APL one-liner ; and verifies the equivalent runtime call. (define mkrv (fn (arr) (get arr :ravel))) (define mksh (fn (arr) (get arr :shape))) ; ---------- reductions ---------- (apl-test "+/⍵ — sum" (mkrv (apl-reduce apl-add (make-array (list 5) (list 1 2 3 4 5)))) (list 15)) (apl-test "(+/⍵)÷⍴⍵ — mean" (mkrv (apl-div (apl-reduce apl-add (make-array (list 5) (list 1 2 3 4 5))) (apl-scalar 5))) (list 3)) (apl-test "⌈/⍵ — max" (mkrv (apl-reduce apl-max (make-array (list 6) (list 3 1 4 1 5 9)))) (list 9)) (apl-test "⌊/⍵ — min" (mkrv (apl-reduce apl-min (make-array (list 6) (list 3 1 4 1 5 9)))) (list 1)) (apl-test "(⌈/⍵)-⌊/⍵ — range" (mkrv (apl-sub (apl-reduce apl-max (make-array (list 6) (list 3 1 4 1 5 9))) (apl-reduce apl-min (make-array (list 6) (list 3 1 4 1 5 9))))) (list 8)) (apl-test "×/⍵ — product" (mkrv (apl-reduce apl-mul (make-array (list 4) (list 1 2 3 4)))) (list 24)) (apl-test "+\\⍵ — running sum" (mkrv (apl-scan apl-add (make-array (list 5) (list 1 2 3 4 5)))) (list 1 3 6 10 15)) ; ---------- sort / order ---------- (apl-test "⍵[⍋⍵] — sort ascending" (mkrv (apl-quicksort (make-array (list 5) (list 3 1 4 1 5)))) (list 1 1 3 4 5)) (apl-test "⌽⍵ — reverse" (mkrv (apl-reverse (make-array (list 5) (list 1 2 3 4 5)))) (list 5 4 3 2 1)) (apl-test "⊃⌽⍵ — last element" (mkrv (apl-disclose (apl-reverse (make-array (list 4) (list 10 20 30 40))))) (list 40)) (apl-test "1↑⍵ — first element" (mkrv (apl-take (apl-scalar 1) (make-array (list 4) (list 10 20 30 40)))) (list 10)) (apl-test "1↓⍵ — drop first" (mkrv (apl-drop (apl-scalar 1) (make-array (list 4) (list 10 20 30 40)))) (list 20 30 40)) (apl-test "¯1↓⍵ — drop last" (mkrv (apl-drop (apl-scalar -1) (make-array (list 4) (list 10 20 30 40)))) (list 10 20 30)) ; ---------- counts / membership ---------- (apl-test "≢⍵ — tally" (mkrv (apl-tally (make-array (list 7) (list 9 8 7 6 5 4 3)))) (list 7)) (apl-test "+/⍵=v — count occurrences of v" (mkrv (apl-reduce apl-add (apl-eq (make-array (list 7) (list 1 2 3 2 1 3 2)) (apl-scalar 2)))) (list 3)) (apl-test "0=N|M — divisibility test" (mkrv (apl-eq (apl-scalar 0) (apl-mod (apl-scalar 3) (apl-scalar 12)))) (list 1)) ; ---------- shape constructors ---------- (apl-test "N⍴1 — vector of N ones" (mkrv (apl-reshape (apl-scalar 5) (apl-scalar 1))) (list 1 1 1 1 1)) (apl-test "(N N)⍴0 — N×N zero matrix" (mkrv (apl-reshape (make-array (list 2) (list 3 3)) (apl-scalar 0))) (list 0 0 0 0 0 0 0 0 0)) (apl-test "⍳∘.=⍳ — N×N identity matrix" (mkrv (apl-outer apl-eq (apl-iota (apl-scalar 3)) (apl-iota (apl-scalar 3)))) (list 1 0 0 0 1 0 0 0 1)) (apl-test "⍳∘.×⍳ — multiplication table" (mkrv (apl-outer apl-mul (apl-iota (apl-scalar 3)) (apl-iota (apl-scalar 3)))) (list 1 2 3 2 4 6 3 6 9)) ; ---------- numerical idioms ---------- (apl-test "+\\⍳N — triangular numbers" (mkrv (apl-scan apl-add (apl-iota (apl-scalar 5)))) (list 1 3 6 10 15)) (apl-test "+/⍳N=N×(N+1)÷2 — sum of 1..N" (mkrv (apl-reduce apl-add (apl-iota (apl-scalar 10)))) (list 55)) (apl-test "×/⍳N — factorial via iota" (mkrv (apl-reduce apl-mul (apl-iota (apl-scalar 5)))) (list 120)) (apl-test "2|⍵ — parity (1=odd)" (mkrv (apl-mod (apl-scalar 2) (make-array (list 5) (list 1 2 3 4 5)))) (list 1 0 1 0 1)) (apl-test "+/2|⍵ — count odd" (mkrv (apl-reduce apl-add (apl-mod (apl-scalar 2) (make-array (list 5) (list 1 2 3 4 5))))) (list 3)) ; ---------- boolean idioms ---------- (apl-test "∧/⍵ — all-true" (mkrv (apl-reduce apl-and (make-array (list 4) (list 1 1 1 1)))) (list 1)) (apl-test "∧/⍵ — all-true with zero is false" (mkrv (apl-reduce apl-and (make-array (list 4) (list 1 1 0 1)))) (list 0)) (apl-test "∨/⍵ — any-true" (mkrv (apl-reduce apl-or (make-array (list 4) (list 0 0 1 0)))) (list 1)) (apl-test "∨/⍵ — any-true all zero is false" (mkrv (apl-reduce apl-or (make-array (list 4) (list 0 0 0 0)))) (list 0)) ; ---------- selection / scaling ---------- (apl-test "⍵×⍵ — square each" (mkrv (apl-mul (make-array (list 4) (list 1 2 3 4)) (make-array (list 4) (list 1 2 3 4)))) (list 1 4 9 16)) (apl-test "+/⍵×⍵ — sum of squares" (mkrv (apl-reduce apl-add (apl-mul (make-array (list 4) (list 1 2 3 4)) (make-array (list 4) (list 1 2 3 4))))) (list 30)) (apl-test "⍵-(+/⍵)÷⍴⍵ — mean-centered" (mkrv (apl-sub (make-array (list 5) (list 2 4 6 8 10)) (apl-div (apl-reduce apl-add (make-array (list 5) (list 2 4 6 8 10))) (apl-scalar 5)))) (list -4 -2 0 2 4)) ; ---------- shape / structure ---------- (apl-test ",⍵ — ravel" (mkrv (apl-ravel (make-array (list 2 3) (list 1 2 3 4 5 6)))) (list 1 2 3 4 5 6)) (apl-test "⍴⍴⍵ — rank" (mkrv (apl-shape (apl-shape (make-array (list 2 3) (list 1 2 3 4 5 6))))) (list 2))