diff options
Diffstat (limited to 'docs/hyper-operators.md')
| -rw-r--r-- | docs/hyper-operators.md | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/docs/hyper-operators.md b/docs/hyper-operators.md new file mode 100644 index 0000000..0953e10 --- /dev/null +++ b/docs/hyper-operators.md @@ -0,0 +1,393 @@ +# Hyper RPN Operators + +Hyper operators operate on **all** values currently on the stack, rather than +just the top one or two. They pop every value, reduce them left-associatively, +and push a single result back. + +The syntax uses square brackets: `[+]`, `[*]`, `[-]`, `[/]`, `[^]`, `[%]`, +`[lg]`, `[log]`, `[ln]`. + +## How Hyper Operators Work + +``` +Input: 1 2 3 4 5 [+] + + Step Stack + ---- ----- + 1 [1] + 2 [1, 2] + 3 [1, 2, 3] + 4 [1, 2, 3, 4] + 5 [1, 2, 3, 4, 5] + [+] [15] + +Result: 15 +``` + +All five values are consumed, summed left-to-right (`((((1 + 2) + 3) + 4) + +5)`), and the single result is pushed back. + +### Requirements + +- At least **two** values must be on the stack, or the operator returns an + error. +- After execution, exactly one value remains on the stack. + +## Arithmetic Hyper Operators + +### `[+]` Sum + +Adds all stack values left-associatively. + +``` +$ gt '1 2 3 4 5 [+]' +15 +``` + +Equivalently: `1 + 2 + 3 + 4 + 5` = 15. + +With two operands, behaves identically to binary `+`: + +``` +$ gt '10 20 [+]' +30 +``` + +### `[*]` Product + +Multiplies all stack values left-associatively. Result is always unitless. + +``` +$ gt '2 3 4 [*]' +24 +``` + +Equivalently: `2 * 3 * 4` = 24. + +``` +$ gt '1 2 3 [*]' +6 +``` + +### `[-]` Subtraction + +Subtracts all stack values left-associatively from the first. + +``` +$ gt '10 3 2 [-]' +5 +``` + +Equivalently: `10 - 3 - 2` = 5. + +``` +$ gt '100 10 20 30 [-]' +40 +``` + +Equivalently: `100 - 10 - 20 - 30` = 40. + +### `[/]` Division + +Divides all stack values left-associatively from the first. Result is always +unitless. + +``` +$ gt '100 5 2 [/]' +10 +``` + +Equivalently: `100 / 5 / 2` = 10. + +``` +$ gt '1000 10 10 [/]' +10 +``` + +### `[^]` Power + +Raises left-associatively. The first value is the base, subsequent values are +successive exponents. Result is always unitless. + +``` +$ gt '2 3 2 [^]' +64 +``` + +Equivalently: `(2 ^ 3) ^ 2` = `8 ^ 2` = 64. + +With two operands, behaves identically to binary `^`: + +``` +$ gt '2 10 [^]' +1024 +``` + +### `[%]` Modulo + +Computes modulo left-associatively. + +``` +$ gt '100 7 3 [%]' +2 +``` + +Equivalently: `100 % 7` = 2, then `2 % 3` = 2. + +``` +$ gt '10 3 2 2 [%]' +0 +``` + +Equivalently: `((((10 % 3) % 2) % 2)` = `(1 % 2) % 2` = `1 % 2` = 1. + +## Logarithmic Hyper Operators + +Logarithmic hyper operators compute the **sum** of the log function applied to +each stack value. All input values must be positive. + +### `[lg]` Base-2 Logarithm Sum + +``` +$ gt '2 4 8 [lg]' +6 +``` + +Equivalently: `log2(2) + log2(4) + log2(8)` = `1 + 2 + 3` = 6. + +``` +$ gt '1 2 3 4 5 [lg]' +6.907 +``` + +### `[log]` Base-10 Logarithm Sum + +``` +$ gt '10 100 [log]' +3 +``` + +Equivalently: `log10(10) + log10(100)` = `1 + 2` = 3. + +### `[ln]` Natural Logarithm Sum + +``` +$ gt '2.718281828 7.389 [ln]' +2.999992408 +``` + +Equivalently: `ln(2.718281828) + ln(7.389)` ≈ `1 + 2` ≈ 3. + +## Metric-Aware Behavior + +Some hyper operators are metric-aware, meaning they understand units and can +operate on values with compatible units. + +### Metric-aware operators: `[+]`, `[-]`, `[%]` + +These operators: + +1. **Validate** that all operands share the same metric category (or are + unitless, which is always compatible). +2. **Convert** all values to the result metric's base units before computing. +3. **Push** the result with the first non-unitless metric (or unitless if all + inputs are unitless). + +``` +$ gt '1km 2km 3km [+]' +6 +``` + +Result is in kilometers: `1 + 2 + 3 = 6 km`. + +``` +$ gt '1km 500m [+]' +1.5 +``` + +`500m` is converted to `0.5km`, then `1km + 0.5km = 1.5km`. + +``` +$ gt '100m 0.005km [+]' +105 +``` + +`0.005km` is converted to `5m`, then `100m + 5m = 105m`. + +``` +$ gt '5km 1km 2km [-]' +2 +``` + +Result is `5 - 1 - 2 = 2 km`. + +``` +$ gt '10m 3m 2m [%]' +1 +``` + +`10 % 3 = 1`, then `1 % 2 = 1 m`. + +``` +$ gt '1km 1000m [+]' +2 +``` + +`1000m` converts to `1km`, result is `1 + 1 = 2 km`. + +### Non-metric operators: `[*]`, `[/]`, `[^]`, `[lg]`, `[log]`, `[ln]` + +These operators use raw numeric values and always produce unitless (Cool) +results, regardless of input units: + +- `[*]` — multiplying meters by meters would yield square meters, a different + category, so the result is unitless. +- `[/]` — dividing two like units yields a ratio, which is unitless. +- `[^]` — exponents are inherently unitless. +- `[lg]`, `[log]`, `[ln]` — logarithms require dimensionless inputs, so the + raw numeric value is used and the result is unitless. + +### Mixed unitless and unit values + +Unitless (Cool) values can be combined with any metric category — they +"absorb" and take on the category of the other operands: + +``` +$ gt '0 5km [+]' +5 +``` + +## Practical Use Cases + +### Batch aggregation + +Sum a series of readings in one command: + +``` +$ gt '12 15 18 14 16 [+]' +75 +``` + +### Running total with metric conversion + +Sum distances in different units: + +``` +$ gt '5km 2km 1000m [+]' +8 +``` + +Result is in km: `5 + 2 + 1 = 8 km`. + +### Compute a product + +``` +$ gt '2 5 10 [*]' +100 +``` + +### Chained reduction with regular operators + +Compare hyper `[+]` with chained binary `+`: + +``` +$ gt '1 2 3 4 5 +' + + + + + + + +' +15 +``` + +Equivalent (but much shorter) with hyper: + +``` +$ gt '1 2 3 4 5 [+]' +15 +``` + +### Cascading subtraction + +``` +$ gt '100 10 20 30 5 [-]' +35 +``` + +`100 - 10 - 20 - 30 - 5 = 35`. + +### Repeated division + +``` +$ gt '1000 2 2 2 2 [/]' +62.5 +``` + +`1000 / 2 / 2 / 2 / 2 = 62.5`. + +### Log sum for information theory + +Sum of log2 values for entropy calculations: + +``` +$ gt '0.25 0.5 0.25 [lg]' +-3 +``` + +`log2(0.25) + log2(0.5) + log2(0.25)` = `-2 + -1 + -2` = -5. + +## Edge Cases + +### Division by zero + +``` +$ gt '10 5 0 [/]' +Error: division by zero +``` + +### Modulo by zero + +``` +$ gt '100 7 0 [%]' +Error: modulo by zero +``` + +### Non-positive log inputs + +``` +$ gt '0 [lg]' +Error: log2 undefined for non-positive numbers + +$ gt '-1 [ln]' +Error: ln undefined for non-positive numbers +``` + +### Incompatible metrics + +Mixing different metric categories (e.g., length and weight) in a metric-aware +operator returns an error. + +### Insufficient operands + +All hyper operators require at least two values: + +``` +$ gt '5 [*]' +Error: insufficient operands for [*]: need at least 2 values + +$ gt '[+]' +Error: stack is empty +``` + +## Summary Table + +| Operator | Description | Metric-aware | Result metric | +|----------|--------------------------------|--------------|---------------| +| `[+]` | Sum all values | Yes | First non-Cool| +| `[*]` | Multiply all values | No | Cool (unitless)| +| `[-]` | Subtract all values | Yes | First non-Cool| +| `[/]` | Divide all values | No | Cool (unitless)| +| `[^]` | Power (left-associative) | No | Cool (unitless)| +| `[%]` | Modulo (left-associative) | Yes | First non-Cool| +| `[lg]` | Sum of log2 for all values | No | Cool (unitless)| +| `[log]` | Sum of log10 for all values | No | Cool (unitless)| +| `[ln]` | Sum of ln for all values | No | Cool (unitless)| |
