Grammar¶
This page documents the grammar implemented by MARPLE's parser (src/marple/parser.py).
Evaluation order¶
APL evaluates right to left. Every function takes everything to its right as its right argument. There is no operator precedence among functions.
This is 2×(3+4), not (2×3)+4.
Binding hierarchy (tightest first)¶
- Bracket indexing --
M[i;j] - Operator binding --
+/,⌽⍤1,∘.×,f.g - Strand formation --
1 2 3(adjacent numbers form a vector) - Function application --
f Y(monadic) orX f Y(dyadic) - Assignment --
name ← value
Valence¶
A function is dyadic if a value appears to its left; otherwise it is monadic. The parser determines valence from context: if the token immediately left of a function glyph is a value (number, variable, or closing paren/bracket), the function is dyadic.
Tokens¶
| Token type | Examples |
|---|---|
| Number | 42, 3.14, ¯5, 1e3 |
| String | 'hello', 'it''s' |
| Function glyph | + - × ÷ ⌈ ⌊ * ⍟ \| < ≤ = ≥ > ≠ ∧ ∨ ~ ⍴ ⍳ , ↑ ↓ ⌽ ⍉ ⍋ ⍒ ⊤ ⊥ ⍎ ⍕ ⌹ ○ ⌷ ≡ ≢ ∈ |
| Operator | / \ . ∘ ⍤ ⌶ |
| Identifier | x, myFunc, total |
| Qualified name | $::io::nread, ns::func |
| System variable | ⎕IO, ⎕CT, ⎕PP |
| Dfn delimiters | { } |
| Dfn special names | ⍵ ⍺ ∇ |
| Guard | : (inside dfns) |
| Diamond | ⋄ (statement separator) |
| Assignment | ← |
| Brackets | [ ] ; (indexing) |
| Parentheses | ( ) (grouping) |
Statements¶
Multiple expressions on one line are separated by ⋄ (diamond). Each statement is parsed independently.
Assignment¶
Assigns the result of expression to name or a system variable. The assigned value is the result (but the REPL suppresses display for bare assignments).
Dfn syntax¶
Inside a dfn:
⍵-- right argument⍺-- left argument∇-- self-reference (recursion)⍺←expr-- default left argumentcondition : expr-- guard
Derived functions¶
| Syntax | Meaning |
|---|---|
f/ Y |
Reduce Y with f |
f\ Y |
Scan Y with f |
X ∘.f Y |
Outer product |
X f.g Y |
Inner product |
(f⍤k) Y |
Rank operator (monadic) |
X (f⍤k) Y |
Rank operator (dyadic) |
(⌶'path') Y |
I-beam (monadic) |
X (⌶'path') Y |
I-beam (dyadic) |
Operator-function composition¶
Reduce and scan can be composed with rank:
Bracket indexing¶
Bracket indexing binds tighter than function application. Empty indices select all elements along that axis.
Dyadic use of / and \¶
When / or \ appears between two values (not after a function glyph), they act as dyadic functions:
X / Y-- replicate/compressX \ Y-- expand
Parentheses¶
Parentheses override the default right-to-left evaluation: