Chris Collins

Lab · Playground

BQN playground

BQN, a modern APL, in your browser — whole-array primitives, folds and scans, tables, and tacit trains like (+´÷≠) for the mean.

Code blocks on this page are editable — change them and press Run.

BQN is Marshall Lochbaum’s 2020 redesign of APL — Kenneth Iverson’s 1960s notation that began as a way of writing about algorithms on a blackboard and became a language. In the APL family you don’t write loops. Every primitive works on whole arrays, so 1 + ↕10 adds one to ten numbers at once; modifiers turn functions into new functions (´` is "sum", +` is "running sum", `×⌜` is "multiplication table"); and short chains of functions, called trains, compose without naming their arguments — `´ ÷ ≠ is "sum divided by count": the mean, in three characters. Code is dense, but each symbol is one idea, and after a while you read ⌽ as "reverse" the way you read + as "plus".

These blocks run the BQN reference implementation in JavaScript (from mlochbaum/BQN), small enough to load at once. The value of the last line is printed, and •Show x prints along the way. To type the symbols, use the BQN keymap or copy them from these examples; # starts a comment.

Arrays first: one operation, every element
•Show ↕10                    # range: 0 to 9
•Show 1 + ↕10                # add one to each
•Show (↕10) × ↕10            # pairwise: squares
•Show 2 ⋆ ↕11                # powers of two
•Show 3‿4 ⥊ ↕12              # reshape into 3 rows of 4
•Show ⌽ "stressed"           # reverse
⍉ 3‿4 ⥊ ↕12                  # transpose
Modifiers: fold, scan, each, and table
•Show +´ 1 + ↕100            # fold with +: sum 1..100
•Show ×´ 1 + ↕10             # fold with ×: 10 factorial
•Show +` 1 + ↕10             # scan: running totals
•Show ⌈` 3‿1‿4‿1‿5‿9‿2‿6     # running maximum
•Show ≠¨ "an"‿"array"‿"of"‿"words"      # each: the length of every word
(1 + ↕9) ×⌜ 1 + ↕9           # table: the 9 × 9 multiplication square
Trains: functions combined without naming the arguments
Mean ← +´ ÷ ≠                # (sum) divided by (count)
Range ← ⌈´ - ⌊´              # (max) minus (min)
Norm ← √ +´∘(ט)             # square root of the sum of the squares

data ← 4‿8‿15‿16‿23‿42
•Show Mean data
•Show Range data
•Show Norm 3‿4

# A fork f g h applied to x is (f x) g (h x).  Variance:
Var ← Mean (ט (⊢ - Mean))
•Show Var data
•Show √ Var data             # standard deviation
Sorting, grading, and selecting
scores ← 72‿95‿64‿88‿95‿51
names ← "Ann"‿"Bo"‿"Cy"‿"Di"‿"Ed"‿"Flo"

•Show ∧ scores               # sort up
•Show ⍒ scores               # grade down: the indices that would sort it
•Show (⍒ scores) ⊏ names     # select names in score order
•Show (scores ≥ 70) / names  # replicate with a boolean mask: filter
•Show ⍷ scores               # deduplicate
•Show +´ scores = ⌈´ scores  # how many share the top score
names ≍ •Fmt¨ scores         # two rows side by side
Blocks: your own functions with 𝕩 and 𝕨
# 𝕩 is the right argument and 𝕨 the left; a block with them is a function
Collatz ← {𝕩 = 1 ? ⟨1⟩ ; 𝕩 ∾ 𝕊 (2|𝕩) ⊑ (𝕩÷2)‿(1+3×𝕩)}
•Show Collatz 6
•Show ≠ Collatz 27

Clamp ← {lo‿hi ← 𝕨 ⋄ lo ⌈ hi ⌊ 𝕩}
•Show 0‿10 Clamp ¯5‿3‿12‿7

# Primes up to 50: the numbers with exactly two divisors.  n |⌜ n is the table of every
# remainder; +˝ sums its columns
Primes ← {n ← 1 + ↕𝕩 ⋄ (2 = +˝ 0 = n |⌜ n) / n}
Primes 50
Text as arrays of characters
text ← "the quick brown fox jumps over the lazy dog"
space ← text = ' '                    # a boolean array, one per character

•Show +´ space                        # how many spaces
•Show (¬ space) / text                # keep what isn't a space

# Split into words: give each letter its word number (spaces so far), each space ¯1, then group
words ← (((¬ space) × +` space) - space) ⊔ text
•Show words
•Show ≠¨ words                        # word lengths
•Show ∧ ⍷ (¬ space) / text            # the distinct letters, sorted
26 = ≠ ⍷ (¬ space) / text             # 1: it's a pangram