diff options
| author | tslil <tslil@posteo.de> | 2026-03-21 15:10:05 +0000 |
|---|---|---|
| committer | tslil <tslil@posteo.de> | 2026-03-21 17:28:51 +0000 |
| commit | fb0d0b91bfd45d1911e993ca753d81da5e60f60c (patch) | |
| tree | 258da432a1b00a399d8f3b9afd1f4504f4d20eee /rprt.md | |
| parent | c22cc3b348bdcb446fb0e44070da36fdf6b05800 (diff) | |
fixing evaluation semantics
Diffstat (limited to 'rprt.md')
| -rw-r--r-- | rprt.md | 30 |
1 files changed, 15 insertions, 15 deletions
@@ -75,32 +75,32 @@ The buffer axis (rank 3) is the **leading axis**: operations on rank 3 selection A **train** is a sequence of functions that compose according to specific rules, following [APL train syntax](https://aplwiki.com/wiki/Train). **2-train (Atop)** `F G`: -- Niladic: `(F G) = F (G)` -- Monadic: `(F G) ω = F (G ω)` -- Dyadic: `α (F G) ω = F (α G ω)` +- Niladic: `F G` = (F) G`; `F` is evaluated niladically and `G` is evaluated monadically on the result +- Monadic: `ω (F G) = (ω F) G` +- Dyadic: `ω (F G) α = (ω F α) G` **3-train (Fork)** `F G H`: -- Niladic: `(F G H) = (F) G (H)` -- Monadic: `(F G H) ω = (F ω) G (H ω)` -- Dyadic: `α (F G H) ω = (α F ω) G (α H ω)` +- Niladic: `F G H` = `(F) G (H)`; `F`, `H` are evaluated niladically and `G` is evaluated dyadically on the result +- Monadic: `ω (F G H) = (ω F) G (ω H)` +- Dyadic: `ω (F G H) α = (ω F α) G (ω H α)` -**Longer trains**: Parsed right-associatively. A train of n functions is parsed by taking the rightmost 3 functions as a fork (if n is odd and ≥3) or the rightmost 2 functions as atop (if n is even), then recursively parsing the remaining functions as the left part. For example: -- 4 functions `F G H I` → `F (G H I)` (atop of F with a fork) -- 5 functions `F G H I J` → `(F G) (H I J)` (atop of an atop with a fork) +**Longer trains**: Parsed left-associatively. A train of n functions is parsed by taking the leftmost 3 functions as a fork (if n is odd and ≥3) or the leftmost 2 functions as atop (if n is even), then recursively parsing the remaining functions as the right part. For example: +- 4 functions `F G H I` → `(F G H) I` (I atop a fork) +- 5 functions `F G H I J` → `(F G H) (I J)` (atop, atop a fork) ### Hooks RPRT provides two explicit hook combinators from BQN for flexible function composition: **Before (Left Hook)** `F>G`: -- Niladic: `(F>G) = (F) G` -- Monadic: `(F>G) ω = (F ω) G ω` -- Dyadic: `α (F>G) ω = (F α) G ω` +- Niladic: `F>G = (F) G`; `F` is evaluated niladically and `G` is evaluated monadically on the result +- Monadic: `ω (F>G) = (ω F) G ω` +- Dyadic: `ω (F>G) α = (ω F) G α` **After (Right Hook)** `F<G`: -- Niladic: `(F<G) = F (G)` -- Monadic: `(F<G) ω = ω F (G ω)` -- Dyadic: `α (F<G) ω = α F (G ω)` +- Niladic: `F<G = ???` TODO: undefined? +- Monadic: `ω (F<G) = ω F (G ω)` +- Dyadic: `ω (F<G) α = ω F (G α)` These combinators bind more tightly than trains and enable partial application patterns. Hooks are **right-associative**, the _opposite_ of BQN's modifier associativity: `F<G<H` parses as `F<(G<H)`. |
