kiki ref

evaluation

kiki reads right to left. Parentheses override.

2 :* 3 :+ 1
8
-- 3+1 first, then *2
(2 :* 3) :+ 1
7

arrays

Numbers separated by spaces form an array. Brackets with ; allow expressions as elements.

1 2 3 4 5
1 2 3 4 5
[1; 2; 3]
1 2 3
# 1 2 3 4 5
5

assignment

name: expr binds a name and returns the value. Names persist for the session.

x: 3 1 4 1 5 9
3 1 4 1 5 9
x
3 1 4 1 5 9
# x
6

monadic verbs

A monadic verb takes one argument: verb arg (prefix) and is comprised of a single glyph.

! 5
0 1 2 3 4
# 3 1 4 1 5
5
| 1 2 3 4 5
5 4 3 2 1
^ 3 1 4 1 5 9
1 1 3 4 5 9
? 1 2 1 3 2 4
1 2 3 4
- 1 2 3
-1 -2 -3
* 9 8 7
9
% 4
0.25
_ 3.7
3
~ 1 0 1 0
0 1 0 1
& 1 0 1 1 0
0 2 3
< 3 1 4 1 5
1 3 0 2 4
> 3 1 4 1 5
4 2 0 1 3
, 42
(42)

dyadic verbs

A dyadic verb takes two arguments. The : prefix marks the dyadic form: left :verb right. Dyadic verbs are always made up of two glyphs, starting with a : prefix.

3 :+ 4
7
10 :- 3
7
3 :* 4
12
7 :% 2
3.5
10 :! 3
1
3 :# 0 1 2 3 4 5
0 1 2
2 :_ 0 1 2 3 4 5
2 3 4 5
1 2 3 4 5 :< 3
1 1 0 0 0
1 2 3 4 5 :> 3
0 0 0 1 1
1 2 3 4 5 := 3
0 0 1 0 0
1 2 3 :, 4 5 6
1 2 3 4 5 6
1 2 3 4 5 :@ 2
3
1 2 3 4 5 :? 3
2
1 2 3 :~ 1 2 3
1

scalar extension

Dyadic verbs broadcast automatically between a scalar and an array, or apply pair-wise between equal-length arrays.

2 :* 1 2 3 4 5
2 4 6 8 10
10 :- 1 2 3 4 5
9 8 7 6 5
1 2 3 4 5 :> 3
0 0 0 1 1
1 2 3 :+ 4 5 6
5 7 9

adverbs

An adverb follows a verb glyph and produces a new monadic function. / folds (reduce), \ scans (running fold), ' maps over each element.

+/ 1 2 3 4 5
15
*/ 1 2 3 4 5
120
&/ 3 1 4 1 5 9
1
|/ 3 1 4 1 5 9
9
+\ 1 2 3 4 5
1 3 6 10 15
*\ 1 2 3 4 5
1 2 6 24 120
|\ 3 1 4 1 5 9
3 3 4 4 5 9
#' ["hi"; "bye"; "hello"]
2 3 5

composition

Expressions compose right to left without extra punctuation.

+/ ! 5
10
-- sum of 0 1 2 3 4
| ^ 3 1 4 1 5 9
9 5 4 3 1 1
-- sort then reverse = descending
# ? 1 2 1 3 2
3
-- count unique values

indexing and filtering

:@ indexes by position. Pair it with & (where) and a comparison to filter.

x: 3 1 4 1 5 9 2 6
x :@ 0
3
x :@ 0 2 4
3 4 5
x :@ (< x)
1 1 2 3 4 5 6 9
-- sort via grade up
x :@ (> x)
9 6 5 4 3 2 1 1
-- sort descending
x :@ (& x :> 4)
5 9 6
-- x:>4 gives 0 0 0 0 1 1 0 1, & gives indices 4 5 7
+/ x :> 4
3
-- count elements above 4

matrices

Nested bracket literals form 2D arrays. + transposes. # counts rows. * takes the first row.

m: [[1;2;3];[4;5;6]]
1 2 3
4 5 6
+ m
1 4
2 5
3 6
# m
2
* m
1 2 3

named helpers

Pre-defined functions. Call like name arg.

sum 1 2 3 4 5
15
prod 1 2 3 4 5
120
min 3 1 4 1 5 9
1
max 3 1 4 1 5 9
9
mean 2 4 6 8 10
6
flat [[1;2];[3;4]]
1 2 3 4
pi
3.14159
e
2.71828

chunk is curried — assign the partial application, then call it.

by3: chunk 3
by3 (1 2 3 4 5 6)
1 2 3
4 5 6

helpers with adverbs

Named helpers work with adverbs. name' maps the helper over each element of an array.

mean' [[1;2;3];[4;5;6]]
2 5
-- mean of each row
sum' [[1;2;3];[4;5;6]]
6 15
-- sum of each row
min' [[3;1;4];[1;5;9]]
1 1
-- min of each row

Combine with chunk to group then aggregate.

-- average each group of 3 by3: chunk 3
mean' (by3 (1 2 3 4 5 6 7 8 9))
2 5 8

capstone: ten days of steps

Daily step counts (thousands) over 10 days. A full analysis using only what we have covered.

-- load the data steps: 8 12 6 15 9 11 7 14 10 13
-- count, total, mean # steps
10
sum steps
105
mean steps
10.5
-- best and worst day max steps
15
min steps
6
(max steps) :- (min steps)
9
-- range
-- distribution (sorted ascending) steps :@ (< steps)
6 7 8 9 10 11 12 13 14 15
-- running total across all 10 days +\ steps
8 20 26 41 50 61 68 82 92 105
-- which days beat the mean? (indices, 0-based) & steps :> 10.5
1 3 5 7 9
+/ steps :> 10.5
5
-- count: 5 out of 10 days
-- step counts on those days steps :@ (& steps :> 10.5)
12 15 11 14 13
mean (steps :@ (& steps :> 10.5))
13
-- top 3 days 3 :# steps :@ (> steps)
15 14 13