sourcedemos/keys.xtl
1⍝!/usr/bin/env xetal
2⍝# Keys: every way X_eTaL is typed. Each line of code appears twice:
3⍝# drawn decorated, as "just pp demos/keys.xtl" shows it, and at the end
4⍝# of the line, after "typed:", exactly the keys you type (a comment is
5⍝# drawn as written, so that text stays plain ASCII). Run it with
6⍝# "xetal run demos/keys.xtl" (or "./demos/keys.xtl") to print each
7⍝# line's result, or "just show demos/keys.xtl" to see each line next to
8⍝# its result. docs/input.md explains each form.
9
10⍝## Names and bindings
11
12⍝# x: a plain variable. := binds it; it is drawn as a left arrow.
13x ← 5 ⍝ typed: x := 5
14
15⍝# count!: a variable whose name ends in ! may be bound again
16⍝# (mutation); the ! is part of the name wherever it is used.
17count! ← 0 ⍝ typed: count! := 0
18count! ← count! + 1 ⍝ typed: count! := count! + 1
19
20⍝ A function name has exactly one underline, typed as _ right after a
21⍝ letter: r_ev is the function "rev" with its r underlined (reverse).
22r̲ev 1 2 3 ⍝ typed: r_ev 1 2 3
23
24⍝# u:s_quare x: x times x. u: puts a name in your program's own
25⍝# namespace (drawn as a raised u). Inside { }, _r is the right argument
26⍝# (drawn as APL's omega).
27ᵘs̲quare ← { ⍵ × ⍵ } ⍝ typed: u:s_quare := { _r * _r }
28ᵘs̲quare 7 ⍝ typed: u:s_quare 7
29
30⍝## Reduce, scan, rotate and reverse, and their axes
31
32⍝# M: a matrix of 2 rows and 3 columns, 1 2 3 above 4 5 6. Axis 1
33⍝# runs down the rows (its length is 2), axis 2 along a row (length 3).
34M ← 2 3 r̲eshape r̲ange 6 ⍝ typed: M := 2 3 r_eshape r_ange 6
35
36⍝ Reduce, r_/ (APL's /), combines items with a function given to it
37⍝ quoted: '+ is plus as a value. With no subscript it works along the
38⍝ first axis, adding the rows together: 1+4, 2+5, 3+6.
39'+ r̲/ M ⍝ typed: '+ r_/ M
40
41⍝ The same with the axis written out: _1 after a function name is
42⍝ axis 1, which is the default, so the result is the same.
43'+ r̲/₁ M ⍝ typed: '+ r_/_1 M
44
45⍝ Axis 2 instead: each row summed along its length: 1+2+3 and 4+5+6.
46'+ r̲/₂ M ⍝ typed: '+ r_/_2 M
47
48⍝ Two digits are two axes: _12 reduces axis 1 and then axis 2, the
49⍝ whole matrix: 21.
50'+ r̲/₁₂ M ⍝ typed: '+ r_/_12 M
51
52⍝ Any function of two arguments reduces: the largest of each row.
53'm̲ax r̲/₂ M ⍝ typed: 'm_ax r_/_2 M
54
55⍝ Scan, s_\ (APL's \), keeps each running result instead of only the
56⍝ last: by default down the rows (row 2 becomes row 1 + row 2) ...
57'+ s̲\ M ⍝ typed: '+ s_\ M
58
59⍝ ... the same with axis 1 written out ...
60'+ s̲\₁ M ⍝ typed: '+ s_\_1 M
61
62⍝ ... and along each row with axis 2: 1, 1+2, 1+2+3.
63'+ s̲\₂ M ⍝ typed: '+ s_\_2 M
64
65⍝ Rotate, o_- (APL's rotate), shifts items round by an amount on its
66⍝ left. By default the rows move: row 2 comes first.
671 o̲- M ⍝ typed: 1 o_- M
68
69⍝ The same with axis 1 written out.
701 o̲-₁ M ⍝ typed: 1 o_-_1 M
71
72⍝ Axis 2 shifts within each row: 2 3 1 and 5 6 4.
731 o̲-₂ M ⍝ typed: 1 o_-_2 M
74
75⍝ A negative amount shifts the other way.
76-1 o̲- 1 2 3 ⍝ typed: -1 o_- 1 2 3
77
78⍝ A list of amounts gives one result for each, as rows.
79-1 0 1 o̲- 1 2 3 ⍝ typed: -1 0 1 o_- 1 2 3
80
81⍝ Reverse, r_ev: by default the order of the rows ...
82r̲ev M ⍝ typed: r_ev M
83
84⍝ ... the same with axis 1 written out ...
85r̲ev₁ M ⍝ typed: r_ev_1 M
86
87⍝ ... and with axis 2, each row reversed.
88r̲ev₂ M ⍝ typed: r_ev_2 M
89
90⍝## Powers
91
92⍝ ^ touching a value, then a number, is an exponent (a superscript).
93x² ⍝ typed: x^2
94
95⍝ A decimal exponent is raised too, its point drawn as a raised dot:
96⍝ the power 0.5 is the square root, of every item.
97(1 9 25)⁰·⁵ ⍝ typed: (1 9 25)^0.5
98
99⍝ A spaced ^ is the power function; use it for a computed power.
100x ^ 3 ⍝ typed: x ^ 3
101
102⍝ ^ touching a function name, then a whole number, applies the
103⍝ function that many times: n_eg (negate) three times.
104n̲eg³ 5 ⍝ typed: n_eg^3 5
105
106⍝## Numbers and minus
107
108⍝ A minus touching a number makes it negative: three numbers.
109-1 0 1 ⍝ typed: -1 0 1
110
111⍝ A spaced minus subtracts.
1123 − 1 ⍝ typed: 3 - 1
113
114⍝ A space before the minus but not after: 3 and negative 1, two
115⍝ numbers ("3-1", with no spaces, is an error: it is ambiguous).
1163 -1 ⍝ typed: 3 -1
117
118⍝ x minus negative 3.
119x − -3 ⍝ typed: x - -3
120
121⍝ A decimal number, and *, drawn as the times sign.
1222.5 × 2 ⍝ typed: 2.5 * 2
123
124⍝## Comparisons and logic
125
126⍝ != is "not equal", drawn as the not-equal sign.
127x ≠ 3 ⍝ typed: x != 3
128
129⍝ <= is "at most", drawn as the less-or-equal sign.
130x ≤ 5 ⍝ typed: x <= 5
131
132⍝ & is "and", | is "or". Everything reads right to left with no
133⍝ precedence, so the comparison on the left needs its parentheses.
134(x > 1) ∧ x < 9 ⍝ typed: (x > 1) & x < 9
135(x < 1) ∨ x > 9 ⍝ typed: (x < 1) | x > 9
136
137⍝## Functions of your own
138
139⍝# x u:a_dd y: x plus y. Inside { }, _l is the left argument (drawn as
140⍝# APL's alpha) and _r the right: this function takes two arguments.
141ᵘa̲dd ← { ⍺ + ⍵ } ⍝ typed: u:a_dd := { _l + _r }
142
143⍝ A function of two arguments is written between them.
1442 ᵘa̲dd 3 ⍝ typed: 2 u:a_dd 3
145
146⍝# u:s_ign n: -1, 0 or 1 as n is negative, zero or positive. n -> names
147⍝# the argument n. "c ? r" is a guard: when c holds, the result is r;
148⍝# statements are separated by ; (drawn as a diamond).
149ᵘs̲ign ← { n → n < 0 ? -1◆ n = 0 ? 0◆ 1 }
150⍝ typed: u:s_ign := { n -> n < 0 ? -1; n = 0 ? 0; 1 }
151ᵘs̲ign -4 ⍝ typed: u:s_ign -4
152
153⍝ A quoted lambda is a function passed as a value: e_ach applies it to
154⍝ every item.
155'{ ⍵ × 10 } e̲ach 1 2 ⍝ typed: '{ _r * 10 } e_ach 1 2
156
157⍝# u:m_ean v: the mean of v. Three functions in square brackets are a
158⍝# train (a fork): the sum divided by the count, which is the mean.
159ᵘm̲ean ← ['+ r̲/ ÷ t̲ally] ⍝ typed: u:m_ean := ['+ r_/ / t_ally]
160ᵘm̲ean 1 2 3 4 ⍝ typed: u:m_ean 1 2 3 4
161
162⍝## Strings, Unit and statements
163
164⍝ Text in double quotes is a string, a vector of characters; c_at
165⍝ joins two.
166"hello" c̲at " world" ⍝ typed: "hello" c_at " world"
167
168⍝ @ is Unit, the value that stands for "nothing"; it has 1 item.
169t̲ally @ ⍝ typed: t_ally @
170
171⍝ ; separates two statements on one line (drawn as a diamond).
1721 + 1◆ 2 + 2 ⍝ typed: 1 + 1; 2 + 2
173
174⍝## Libraries and system names
175
176⍝ A library is imported with u_se< (a macro, drawn bold): the left
177⍝ string is the prefix its names get here, the right one its name. The
178⍝ import is drawn as a raised c and a raised equals sign.
179ᶜ⁼u̲se< "Combinators" ⍝ typed: "c:" u_se< "Combinators"
180
181⍝ The library's names, written with that prefix: K keeps its first
182⍝ argument.
1831 ᶜK̲ 2 ⍝ typed: 1 c:K_ 2
184
185⍝ f_ormat gives a value as the text it prints as.
186f̲ormat 3.5 ⍝ typed: f_ormat 3.5
187
188⍝ [] touching an uppercase name is a system name (drawn as APL's quad):
189⍝ []N_PUT writes the text on its left to the file on its right and
190⍝ gives how many characters it wrote.
191"hi" ⎕N̲PUT "work/keys.txt" ⍝ typed: "hi" []N_PUT "work/keys.txt"