“Code is read more often than written.”
X̲ᵉTᵃL
Syntax you can see
Typography carries semantic information.
1. Name decorations
A glance tells you what a name is and where it came from.
r̲evᵘs̲quareᶜK̲ᵐpix
Underlined first character → function
Superscript → provenance / namespace
No underline → value / variable
2. Import a library
The alias becomes visible wherever an imported name is used.
ᶜ⁼u̲se< "Combinators"
Typed: "c:" u_se< "Combinators"
ᶜK̲ 42 17Seeing superscript ᶜ tells the reader which import to find.
3. Definitions
Functions, variables, binding, and lambdas.
ᵘs̲quare ← { ⍵ × ⍵ }
limit ← 100
x = 3
← binds (typed :=); = compares. A variable takes no u: prefix.
4. Apply or pass?
Juxtaposition applies; quote passes a function value.
f̲ x
apply f to x
'f̲ e̲ach values
pass f as a value
'+ r̲/₂ A
Higher-order functions replace a separate operator class.
5. Axes
Subscripts visually attach axes to the function they modify.
r̲/ A
r̲/₂ A
o̲-₁₂ A
default axis · axis 2 · axes 1 and 2
o̲\ A
o̲\₂₃ A
transpose: every axis reversed · axes 2 and 3 swapped
6. Power
Superscript means numeric power or repeated function application.
x²
value exponent
ᵘl̲ife⁴ board
apply life four times
7. Lambdas
Braces define an anonymous function.
{ ⍺ + ⍵ }⍺ (typed _l) left argument
⍵ (typed _r) right argument
⍵ (typed _r) right argument
8. System names
APL quad marks system facilities; function decoration still applies.
⎕N̲GET⎕N̲PUT⎕R̲EAD⎕G̲RID⎕P̲ATH⎕S̲HOW
read a file · write a file · read a typed line · draw cells · draw a line · show a picture
flyover ← ⎕S̲HOW ⎕G̲RID ᵘp̲ass 11
Rendered form only: no literal underscore or [] appears here.
9. The ? symbol
Context distinguishes a guard delimiter from punctuation in a name.
n ≤ 1 ? 1◆ n × f̲ na guard: when n ≤ 1, the result is 1; ◆ (typed ;) separates statements
e̲mpty?
No user-defined operator class: compose behavior with ordinary higher-order functions.
10. ASCII input → rendered
Only this panel deliberately shows raw source notation.
u:s_quare
[]R_EAD
r_/_2
u:l_ife^4
"c:" u_se< "Combinators"
[]R_EAD
r_/_2
u:l_ife^4
"c:" u_se< "Combinators"
ᵘs̲quare
⎕R̲EAD
r̲/₂
ᵘl̲ife⁴
ᶜ⁼u̲se< "Combinators"
⎕R̲EAD
r̲/₂
ᵘl̲ife⁴
ᶜ⁼u̲se< "Combinators"
11. Trains
Square brackets compose functions without naming the argument. Before one value a train is monadic (x is its argument); between two it is dyadic (x and y). Each card gives the rule, then an example and its value.
Atop
two functions: the right one first
[f̲ g̲] x means f̲ g̲ x
[n̲eg a̲bs] -3 4 gives -3 -4
Dyadic atop
the right one takes both arguments
x [f̲ g̲] y means f̲ (x g̲ y)
7 [n̲eg −] 2 gives -5
Fork
the outer two apply, the middle joins
[f̲ g̲ h̲] x means (f̲ x) g̲ (h̲ x)
['+ r̲/ ÷ t̲ally] 1 2 3 4 gives 2.5
Dyadic fork
the outer two take both arguments
x [f̲ g̲ h̲] y means (x f̲ y) g̲ (x h̲ y)
5 [+ × −] 3 gives 16
Hook
a fork whose left function is i̲d
[i̲d f̲ g̲] x means x f̲ (g̲ x)
[i̲d − n̲eg] 5 gives 10
Self
i̲d on both sides: x used twice
[i̲d f̲ i̲d] x means x f̲ x
[i̲d × i̲d] 5 gives 25
Tacks
x l̲eft y is x; x r̲ight y is y
x [l̲eft f̲ r̲ight] y means x f̲ y
7 [l̲eft − r̲ight] 2 gives 5
Longer trains
group into forks from the right
[f̲ g̲ h̲ j̲ k̲] x means [f̲ g̲ [h̲ j̲ k̲]] x
[f̲irst c̲at 'm̲ax r̲/ c̲at t̲ally] 3 1 4 gives 3 4 3
Quoted or named
a train as a value is monadic
'[f̲ g̲] e̲ach v means '{ i → f̲ g̲ i } e̲ach v
'[t̲ally d̲isclose] e̲ach "ab" "cde" "f" gives 2 3 1