

# Shared language rules

[Glyph index](glyphs.qmd)

## Reading expressions

Five rules decide how code reads. [Language principles](principles.qmd)
explains why the notation works this way.

1.  **Brackets and parentheses.** [Brackets](glyphs/brackets.qmd) write
    vectors: `[a b c]`, and `[x]` is a one-item vector. A strand of
    literals can leave them out: `1 2 3` is one vector. Parentheses
    round a literal or glyphs separated by spaces make a scalar: `(1 2)`
    is `⊂1 2`. Round anything else, including a name, they group. With
    `⋄`, they write a vector of rows: `(4 ⋄ 4 5)` is `[[4] [4 5]]`.
2.  **Runs.** A *run* is a sequence of tokens with no spaces between
    them. A bracketed, parenthesised or braced group counts as one
    token. Each run is evaluated first, and then the runs combine.
    Parentheses round an expression group it.
3.  **Application.** Right to left, with no precedence between
    functions. A function takes everything to its right as its right
    argument, and the array directly to its left as its left argument.
    An operator takes the function to its left and one item to its
    right. A run that ends in a dyadic operator takes the next run as
    that item. An array next to an argument selects from it: `v(⍋v)`
    sorts `v`.
4.  **Trains.** A run that ends in a function is a *train*, a function
    built from the right.
5.  **Assignment.** `←` assigns to the run before it, and its value is
    everything after it.

``` apl
2×3+4                ⍝ 14
2×3 + 4              ⍝ 10
(2×3)+4              ⍝ 10
10-3-2               ⍝ 9
```

### Terms

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr>
<th>Term</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td>literal</td>
<td>a number, character, string, <code>∞</code> or <code>⍬</code></td>
</tr>
<tr>
<td>strand</td>
<td>literals separated by spaces, read as a vector without brackets:
<code>1 2 3</code> is <code>[1 2 3]</code></td>
</tr>
<tr>
<td>scalar</td>
<td>an array of rank 0, holding one value: <code>⊂5</code> is a scalar
holding the number 5, and <code>5</code> is a number</td>
</tr>
<tr>
<td>unit</td>
<td>a rank-0 value: a number, character, function or scalar</td>
</tr>
<tr>
<td>run</td>
<td>a sequence of tokens with no spaces between them</td>
</tr>
<tr>
<td>argument</td>
<td>an array a function applies to</td>
</tr>
<tr>
<td>operand</td>
<td>a function or array an operator applies to</td>
</tr>
<tr>
<td>application</td>
<td>an array next to an argument, selecting from it:
<code>v 0</code></td>
</tr>
<tr>
<td>expression</td>
<td>a run, group or statement that ends in an array</td>
</tr>
<tr>
<td>train</td>
<td>a run, group or statement that ends in a function</td>
</tr>
<tr>
<td>fork</td>
<td>three parts of a train, <code>f g h</code>, giving
<code>(f ⍵) g (h ⍵)</code></td>
</tr>
<tr>
<td>constant</td>
<td>an array as the left part of a fork: <code>A g h</code> gives
<code>A g (h ⍵)</code></td>
</tr>
<tr>
<td>Atop</td>
<td>two parts of a train, <code>f g</code>, giving
<code>f (g ⍵)</code></td>
</tr>
<tr>
<td>bind</td>
<td>an array directly before a function in a train, fixing its left
argument: <code>2×</code> is <code>2⊸×</code></td>
</tr>
</tbody>
</table>

### Strands

Numbers in every form, `∞`, `¯∞`, `⍬`, characters and strings are
literals. Literals separated by spaces form a *strand*, which is one
vector. Names never join a strand, including system constants such as
`•a`. Strands form when the source is read, before runs form. Inside
brackets without `;`, every space separates items, so strands don’t form
there.

### Brackets and parentheses

[Brackets](glyphs/brackets.qmd) always write a vector, whatever the
number of items: `[5]` is a one-item vector. `;` separates items that
contain spaces. `⋄` stacks rows into an array of higher rank. Each row
is a major cell, so a row that is a single number has rank 0, and
`[1 ⋄ 2]` is the vector `1 2`. A column is written `[[1] ⋄ [2]]`.

[Parentheses](glyphs/parentheses.qmd) round a literal, a strand, or
glyphs separated by spaces make a scalar holding it: `(5)`, `(1 2)`,
`(+)` and `(+ -)`, which holds the vector `[+ -]`. Glyphs that touch
form a train, so `(-×)` groups. Parentheses round anything else group
it, including a name, whatever the name holds. So a literal has a
spelling at every rank: `(1 2)` is rank 0, `[1 2]` is rank 1, and
`[1 2 ⋄ 3 4]` is rank 2.

With `⋄`, parentheses write a vector of rows instead. Each row reads as
brackets do, so every row is a vector, even a row with one item:
`(4 ⋄ 4 5 ⋄ 4 5 6)` is `[[4] [4 5] [4 5 6]]`. A trailing `⋄` makes a
one-item vector holding one row: `(1 2 ⋄)` is `[[1 2]]`. Brackets write
flat arrays, and parentheses nest.

``` apl
⍴[5]                 ⍝ [1]
⍴[[1] ⋄ [2]]         ⍝ 2 1
(1 2)≡⊂1 2           ⍝ 1
(4 ⋄ 4 5)≡[[4] [4 5]]  ⍝ 1
(1+2)×3              ⍝ 9
```

``` apl
+/1 2 3              ⍝ 6
≢"ab" "cd"           ⍝ 2
a←1 ⋄ b←2 ⋄ [a b]    ⍝ 1 2
```

### Runs

Spaces separate runs outside brackets. A line break inside parentheses
or brackets counts as a space. Inside braces, a line break separates
statements. Each run must reduce to one value: an array, a function, or
a lone operator such as the `/` in `+ / x`. Otherwise it is a `SYNTAX`
error.

``` apl
a←1 ⋄ b←2 ⋄ c←3 ⋄ d←4 ⋄ a+b × c+d   ⍝ 21
x←3 ⋄ x+1 ÷ 2                        ⍝ 2
+ / 1 2 3                            ⍝ 6
```

### Operators and operands

Operators bind before function application. An operator’s left operand
is the whole function to its left. Its right operand is the one item to
its right. A run ends at a space, so `f⍤1 M` applies `f` at rank 1 to
`M`. A strand is one item, so `f⍤1 2 M` has rank `1 2`. A literal
argument after a literal operand needs brackets: `f⍤1 [2 3]`. A run that
ends in a dyadic operator takes the next run as its right operand, as if
no space came between them. So `f⍤ 1 M` is `f⍤1 M`, and a named operator
takes a literal operand after a space: `+Depth 0 x`, where `Depth0`
would be one name.

``` apl
m←2 3⍴⍳6 ⋄ +/⍤1 m               ⍝ 3 12
m←2 3⍴⍳6 ⋄ +/⍤ 1 m              ⍝ 3 12
x←5 ⋄ 1+⍣3 x                     ⍝ 8
```

Names hold arrays, functions or operators, resolved at execution time.
Arrays contain numbers, characters, functions and arrays.

### Application

An array next to an argument selects along its leading axis, with
positions as in [Index](glyphs/squad.qmd) `⌷`. The result has the shape
of the positions, followed by the shape of each selected cell. `v 1`
gives item 1, `v(1)` gives it enclosed, and `v[1]` gives a one-item
vector. Application groups from the right: `v w i` is `v (w i)`. Its
argument is everything to its right, so `v 2×3` is `v` applied to 6.

``` apl
v←10 20 30 40 ⋄ v[2 0]          ⍝ 30 10
v←10 20 30 40 ⋄ v ¯1            ⍝ 40
v←10 20 30 40 ⋄ v(1)            ⍝ (20)
v←10 20 30 40 ⋄ v[1]            ⍝ [20]
```

### Trains

A train is built from its last function leftwards, as in APL. A function
and the item before it make a *fork* with what is built so far: `f g h`
gives `(f ⍵) g (h ⍵)`. When that item is an array, it is a *constant*:
`A g h` gives `A g (h ⍵)`. An array directly before what is built
*binds* to it, so `2×` is `2⊸×`. A function left over at the start makes
an *Atop*: `f g` gives `f (g ⍵)`.

``` apl
f←32+1.8× ⋄ f 100    ⍝ 212
(+/÷≢) 1 2 3 6       ⍝ 3
(0.5×⊢+÷) 2          ⍝ 1.25
2 (1-×) 5            ⍝ ¯9
```

With two arguments, a fork `f g h` gives `(⍺ f ⍵) g (⍺ h ⍵)`. A constant
fork `A g h` gives `A g (⍺ h ⍵)`, and an Atop `f g` gives `f (⍺ g ⍵)`. A
bound function takes one argument, so `3 (2×) 4` is a `SYNTAX` error.

A space before an argument decides the reading. `+/÷≢ x` is the mean of
`x`, and `+/÷≢x` is `+/(÷(≢x))`. Where a train’s arrays and functions
alternate, as in `32+1.8×`, both readings give the same result. A name
followed by a name needs a space, so an expression passes a name’s
argument in parentheses: `1+⌽f(x)`. Parentheses round a literal would
enclose it, so a literal argument goes inside the parentheses with its
function: `1+⌽(f 5)`. A run that starts with a function is a call, so
`×2` is the sign of 2.

### Assignment

The target of `←` is the run before it: a name, a selection such as
`v[2]` or `T.x`, a list of names such as `[a b]`, or one of these
followed by a function for [modified assignment](glyphs/assign.qmd). A
named function joins the target in parentheses, because a space would
end the run: `a(f)←3` is `a←a f 3`, at top level and in dfns. The value
is everything to the right of `←`, up to the end of the statement or
group. `a←1 b←2` is not two assignments, because the first `←` takes
`1 b←2` as its value. Independent assignments need `⋄`.

``` apl
v←10 20 30 ⋄ v[1]←7 ⋄ v          ⍝ 10 7 30
[a b]←3 4 ⋄ a×b                  ⍝ 12
a←1 ⋄ f←+ ⋄ a(f)←3 ⋄ a           ⍝ 4
```

### Precedence

From tightest to loosest:

1.  within a run, right to left
2.  across runs, right to left
3.  the pipe `→`, whose stages run left to right
4.  assignment `←`
5.  the guards `:` and `::`
6.  the statement separator `⋄`

Spaces change grouping only at the first two levels.

`→` separates pipeline stages. Each function receives the previous
result as its right argument. `←` takes the whole pipeline as its value.

``` apl
total←1+2×3 → 2× ⋄ total   ⍝ 14
```

### Mixed spacing

- `x ×2` is `x` applied to the sign of 2, so it selects item 1 of `x`
  with no error.
- `10 -/1 2 3` applies `10` as an array to the reduction. With a vector
  on the left, it selects with no error. A seeded reduction needs the
  same spacing on both sides of the function: `10-/1 2 3`.
- `x[2]+ 1` is a `SYNTAX` error. The run `x[2]+` is a train in which
  `[2]` and `x` both bind to `+`. The sum of item 2 and 1 is `(x 2)+1`.

## Numbers

Bare numbers are approximate (`f64`). `x` or `ₓ` marks exact integers;
`r` marks exact rationals. Exact integers display with `ₓ`. Examples use
`x` for typed input. Exact arithmetic grows as needed. Mixing exact and
approximate gives approximate.

``` apl
1÷3                  ⍝ 0.3333333333333333
1x÷3x                ⍝ 1r3
1r3+1r6              ⍝ 1r2
1r2+0.5              ⍝ 1
9223372036854775807x+1x ⍝ 9223372036854775808ₓ
```

`ajb`: a + bi, with approximate components. `J` also parses. `¯` marks
negative literals and exponents.

``` apl
1j2+3j4              ⍝ 4j6
1E¯3                 ⍝ 0.001
```

Predicates, positions, tally, shape, and monadic `⌊`, `⌈` and `×` return
exact integers. A float beyond the `i64` range floors to an exact big
integer. Iota and random integer generation preserve exact arguments. An
argument that must be an integer, such as an index or a count, accepts a
float within comparison tolerance of one:

``` apl
⌊2.5 ¯2.5            ⍝ 2ₓ ¯3ₓ
⌊2*70                ⍝ 1180591620717411303424ₓ
⍳(0.1×3)×10          ⍝ 0 1 2
```

Numbers that an operation puts in one array share a kind. A float among
exact integers makes them all floats, and a complex number makes every
number complex:

``` apl
(⍳3ₓ),0.5            ⍝ 0 1 2 0.5
(⍳2ₓ),1j2            ⍝ 0 1 1j2
(1ₓ,0.5)÷2ₓ          ⍝ 0.5 0.25
```

Items written in a literal list or in brackets keep each number’s
exactness, so exact and approximate numbers written together stay mixed.
Floats written beside complex numbers become complex, which changes no
value:

``` apl
1ₓ 0.5÷2ₓ            ⍝ 1r2 0.25
[1ₓ;0.5]÷2ₓ          ⍝ 1r2 0.25
```

A rational has no compact form, so an array that holds one keeps each
item’s kind. So does an array that also holds characters, nested arrays
or functions, and so does an imported JSON object. Selecting from,
catenating or assigning into this mixed storage keeps each item’s kind.
Arithmetic builds fresh storage, so `1×x` makes every number a float.
Boxed display marks mixed storage with `+`.

Reals include `∞` and `¯∞`. `DOMAIN`: NaN, non-finite complex
components, undefined infinity arithmetic, `⍟0`, division by zero except
`0÷0=1`.

An infinity never makes exact numbers approximate. `⌊` and `⌈` return an
exact argument unchanged beside one. An array of exact integers and an
infinity keeps each item’s kind, in mixed storage. Arithmetic with an
infinity gives floats:

``` apl
3ₓ⌊∞                 ⍝ 3ₓ
(⍳3ₓ),∞              ⍝ 0ₓ 1ₓ 2ₓ ∞
```

## Arrays, nesting and fill

The *based arrays* model was named in a [1981
paper](https://dl.acm.org/doi/abs/10.1145/586656.586663) and popularized
by [BQN](https://mlochbaum.github.io/BQN/doc/based.html).

Numbers, characters and functions are atoms. Arrays are rectangular
collections of values. Shape lists axis lengths; rank is shape’s length.
Scalars, vectors and matrices are arrays of rank 0, 1 and 2. A scalar is
distinct from an atom. Atoms have rank zero for shape operations.
Constructors such as Enclose, Ravel and Reshape create arrays. Ravel
order is row-major. Zero dimensions retain the other dimensions.

Structural mapping (arithmetic, Each and indexing) preserves the mapped
container, including scalars. Cell application (Rank and search)
consumes complete cells, returning one result directly or assembling
results over surrounding batch axes.

``` apl
⍴3                   ⍝ 0⍴0ₓ
⍴,3                  ⍝ ,1ₓ
⍴2 3⍴⍳6              ⍝ 2ₓ 3ₓ
⍴0 3⍴0               ⍝ 0ₓ 3ₓ
```

[Brackets](glyphs/brackets.qmd) write vectors: `[a b c]`. A strand of
literals can leave them out: `1 2 3`. Nothing else forms a vector from
separate items. `[Y]` is a one-item vector. `⊂Y` encloses any value, and
parentheses enclose a literal or glyphs separated by spaces. `↑`
retrieves the first item. Enclosure always adds an array layer.

``` apl
↑[1 2;3 4]           ⍝ 1 2
(⊂3)≡3              ⍝ 0ₓ
(⊂3)=3              ⍝ (1ₓ)
(⊂3)+4              ⍝ (7)
≢¨[1 2 3;4 5]        ⍝ 3ₓ 2ₓ
```

Fill follows the first item’s prototype: zero, space, or recursively
filled nesting. Empty arrays retain a prototype. Assembly pads unequal
cells with fill.

``` apl
5↑1 2                ⍝ 1 2 0 0 0
3↑""                 ⍝ "   "
↑0⍴[1 2;3 4 5]       ⍝ 0 0
```

## Agreement and pervasion

Scalar functions align leading axes. Missing trailing dimensions count
as 1. Equal dimensions agree. A dimension of length 1 expands, including
to zero. Axes of length 1 remain. Other mismatches: `LENGTH`.

``` apl
[1 2 3 ⋄ 4 5 6]+10 20 ⍝ [11 12 13 ⋄ 24 25 26]
[[10] ⋄ [20]]+[1 2 3 ⋄] ⍝ [11 12 13 ⋄ 21 22 23]
⍴[[10] ⋄]+1 2 3       ⍝ 3ₓ 1ₓ
```

Pervasion repeats these rules inside nested items. Each and rank frames
also use leading agreement. Products, replication, indexing and
assignment have their own rules.

This extends APL agreement. NumPy aligns trailing axes.

## Axes and indices

Positions and axes count from 0. Negative positions and axes count from
the end. Counts and positions must be exactly integral, without
tolerance. An array next to an argument selects along its leading axis:
`m 1` is row 1, the second row. [Index](glyphs/squad.qmd) `⌷` selects
along several axes, and `∞` selects a whole axis. After an array, [dot
indexing](glyphs/dot.qmd) writes the same selection: `m.[∞ 1]` is
`∞ 1⌷m`.

[Axis](glyphs/axis.qmd) `⍠` applies a function along axes given as
numbers or names, as in `+/⍠0` and `+/⍠"month"`. [Rank](glyphs/rank.qmd)
`⍤` applies it to trailing cells, and `⍤0` passes each element as a
unit. `/ \ ⌽ ,` default to the last axis, and `⌿ ⍀ ⊖ ⍪` to the first.
Partition `N⊂Y` and `N⊆Y` splits along the first axis. Encode `⊤` puts
its digits on the last axis, and Decode `⊥` reads them from it.
Structural functions also accept axis lists.

``` apl
m←[1 2 3 ⋄ 4 5 6]
m 1                  ⍝ 4 5 6
∞ 1⌷m                ⍝ 2 5
+/⍠0 m               ⍝ 5 7 9
```

## Equality and ordering

Exact/exact comparison is exact. Approximate comparison uses relative
tolerance `1E¯14`. Infinity equals itself, never a finite number.

``` apl
0.3=0.1+0.2          ⍝ 1ₓ
1r3=1x÷3x            ⍝ 1ₓ
```

Search functions compare major cells. `⍳` and `⍸` search their left
argument, and `∊ ~ ∩` search their right. The other argument’s cells
have the same rank as the searched argument’s major cells. A unit has no
major cells, so the searched argument must not be a unit: `s~" "`
removes spaces, and `s~' '` is a `RANK` error.

Search, membership, match and grouping use tolerant comparison.
Tolerance is not transitive, so search and grouping use the first
matching representative.

Grade and interval index ignore tolerance. Order: numbers, characters,
nested arrays. Numbers compare by value; complex numbers by real then
imaginary part; characters by code point. Nested arrays compare rank,
then ravel lexicographically, then shape, ignoring prototypes. Grade is
stable. Scalar ordering (`< ≤ > ≥ ⌊ ⌈`) requires reals.

## Functions and effects

Dfns use lexical scope. Plain assignment is local. Modified and
selective updates target the nearest binding. Arrays have value
semantics: updating one name leaves other copies unchanged.

``` apl
a←1 2 ⋄ b←a ⋄ (a 0)←9 ⋄ b ⍝ 1 2
```

A dfn returns its first result-producing non-assignment expression, or
its final assignment silently. Top-level assignments also retain their
value without display.

Evaluation is right-to-left, including fork arms. Items inside brackets
evaluate left-to-right, as statements do.

Empty Each/rank calls the operand on prototypes. Empty scan makes no
calls. Generic reduction associates right; float sum/product may
reassociate. All scans accumulate left-to-right.

## Errors

<table>
<thead>
<tr>
<th>Error</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>DOMAIN</code></td>
<td>Invalid values or unknown inverse</td>
</tr>
<tr>
<td><code>RANK</code> / <code>LENGTH</code></td>
<td>Invalid rank or shape/count agreement</td>
</tr>
<tr>
<td><code>INDEX</code></td>
<td>Invalid position</td>
</tr>
<tr>
<td><code>SYNTAX</code></td>
<td>Invalid syntax or call form</td>
</tr>
<tr>
<td><code>VALUE</code></td>
<td>Undefined name or missing value</td>
</tr>
</tbody>
</table>

Errors retain source locations. Unsupported features and resource limits
have separate errors.
