Skip to content

Commit

Permalink
Tweak advanced DSL docs
Browse files Browse the repository at this point in the history
  • Loading branch information
frostburn committed May 4, 2024
1 parent 16498fb commit 1140790
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 50 deletions.
109 changes: 59 additions & 50 deletions documentation/advanced-dsl.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ for (const k in {a: 123, b: 456}) {
1 k
}
```
results in `$ = [1 "b", 1 "a"]`. With records the order is indeterministic.
results in `$ = [1 "b", 1 "a"]`. With records the order of iteration is indeterministic.

## Break
"While" and "for" loops can be broken out of using the `break` keyword.
Expand Down Expand Up @@ -120,7 +120,7 @@ result is `$ = [2, 3, 5, 7, 11]`.
### Array comprehensions
"For" loops have an inline counterpart in array comprehensions e.g.
```c
[2 ^ i /^7 for i of [1..7]]
[2 ^ i/7 for i of [1..7]]
```
results in `$ = [2^1/7, 2^2/7, 2^3/7, 2^4/7, 2^5/7, 2^6/7, 2]`.

Expand All @@ -145,7 +145,7 @@ if (3/2 > 700.) {
### Ternary expressions
Conditional expressions look similar but work inline e.g. `3 if true else 5` evaluates to `3` while `3 if false else 5` evaluates to `5`.

#### Vectorizing ternary
#### Vectorizing where...else
Ternary expressions short-circuit i.e. only the test expression and the chosen result are ever evaluated. The vectorizing/broadcasting variant evaluates everything but works on arrays: `[1, 2] where [true false] else 10` evaluates to `[1, 10]`.

## Function declaration
Expand Down Expand Up @@ -194,22 +194,15 @@ try {
}
```

## Lest expressions
The inline version of `try..catch` is called `lest`. The former expression is tried and replaced by the latter on failure.
```javascript
fraction(P5) lest P5 // Successfully evaluates to 3/2
fraction(PI) lest PI // Falls back to 3.141592653589793r
```

## Implicit mapping
The default action when encountering a function is to remap the current scale using it.
Recall that the default action when encountering a function is to remap the current scale using it. Arrow functions are very handy here:
```javascript
primes(3, 17)
prime => prime rd 2
2
sort()
```
First results in `$ = [3, 5, 7, 11, 13, 17]` which gets reduced to `$ = [3/2, 5/4, 7/4, 11/8, 13/8, 17/16]`. Adding the octave and sorting gives the final result `$ = [17/16, 5/4, 11/8, 3/2, 13/8, 7/4, 2]`.
This first results in `$ = [3, 5, 7, 11, 13, 17]` which gets reduced to `$ = [3/2, 5/4, 7/4, 11/8, 13/8, 17/16]`. Adding the octave and sorting gives the final result `$ = [17/16, 5/4, 11/8, 3/2, 13/8, 7/4, 2]`.

Or the same with a oneliner `sorted(primes(17) rdc 2)` demonstrating the utility of broadcasting and *ceiling reduction* in a context where the unison is implicit and coincides with repeated octaves.

Expand Down Expand Up @@ -260,52 +253,64 @@ The expression `1,2` for `6/5` is problematic when you consider the rest of the
### Recommendations
To avoid ambiguity use explicit cents i.e. `100.0c` or explicit scientific notation i.e. `1.2e0` or just `1.2e`.

### Fractional Just Intonation Subgroups
## Fractional Just Intonation Subgroups
By default monzos are vectors of prime exponents and vals are maps of primes, but sometimes you may wish to use other rational numbers as the basis.

Let's take a look at [Barbados temperament](https://en.xen.wiki/w/The_Archipelago#Barbados). We can treat `13/5` like a prime alongside `2` and `3` and map it to `7\5`. The syntax is `[email protected]/5` or `<5 8 7]@2.3.13/5`. Now `<5 8 7]@2.3.13/5 dot 15/13` evaluates to 1 step, exactly half of the 2 steps that an approximate `4/3` spans, as desired.

An explicit subgroup may be given with monzos as well e.g. `[0 1 -1>@2.3.13/5` for `logarithmic(15/13)`.

## Universal monzos
The monzo basis also supports the special symbols `s`, `Hz`, `-1`, `0`, `rc` and ``. A conversion like `monzo(-440Hz)` evaluates to
```c
// Hz, -1, 2, 3, 5, 7, 11
[ 1, 1, 3, 0, 1, 0, 1 >@Hz.-1.2..
```
or `1Hz * (-1) * 2^3 * 5^1 * 11^1` if you break it down linearly.

Two dots after a prime number indicate that exponents of successive primes follow.

### True tone-splitters
Technically the term _semitone_ is a misnomer because the diatonic semitone `m2` doesn't split the tone `M2` in half with mathematical precission (and neither does the chromatic semitone `a1`). The true semiwholetone `M2 % 2` is notated using interordinals as `n1.5` (or `n1½`).

The difference `n1.5 - m2` is only `11.730c` so true tone-splitters are not very useful in their untempered form, but they do provide the notation `n4.5` for the semioctave `P8 % 2` which is stable in all even equal divisions of the octave.
The difference `n1.5 - m2` is only `11.730c` so true tone-splitters are not very useful in their untempered form, but they do provide the notation `n4.5` for the semioctave `P8 / 2` which is present in all even equal divisions of the octave and stays in place during tempering.

The basic tone-splitters are as follows:
| Name | Logarithmic | Linear | Size in cents |
| ---------------------------- | ------------------ | ----------------- | ------------- |
| Neutral sesquith | `n1.5`, `M2 % 2` | `sqrt(9/8)` | `101.955` |
| Neutral sesquith | `n1.5`, `M2 / 2` | `sqrt(9/8)` | `101.955` |
| Neutral second-and-a-halfth | `n2.5`, `M2 * 3/2` | `sqrt(729/512)` | `305.865` |
| Neutral third-and-a-halfth | `n3.5`, `M2 * 5/2` | `9/8 ^ 5/2` | `509.775` |
| Neutral fourth-and-a-halfth | `n4.5`, `P8 % 2` | `sqrt(2)` | `600.000` |
| Neutral fifth-and-a-halfth | `n5.5`, `M10 % 2` | `sqrt(81/32)` | `803.910` |
| Neutral sixth-and-a-halfth | `n6.5`, `a12 % 2` | `sqrt(6561/2048)` | `1007.82` |
| Neutral seventh-and-a-halfth | `n7.5`, `m14 % 2` | `sqrt(32/9)` | `1098.045` |
| Neutral fourth-and-a-halfth | `n4.5`, `P8 / 2` | `sqrt(2)` | `600.000` |
| Neutral fifth-and-a-halfth | `n5.5`, `M10 / 2` | `sqrt(81/32)` | `803.910` |
| Neutral sixth-and-a-halfth | `n6.5`, `a12 / 2` | `sqrt(6561/2048)` | `1007.820` |
| Neutral seventh-and-a-halfth | `n7.5`, `m14 / 2` | `sqrt(32/9)` | `1098.045` |

### Absolute semioctave dodecanominal notation
When stacked against the semioctave the fifth spans a dodecatonal scale inside the octave (10L 2s "soft-jaric" a.k.a. "jaramechromic").

The scale is nominated such that the Greek nominals form the Ionian mode starting from the semioctave.

| Nominal | ASCII | Meaning |
| ------- | -------- | ----------- |
| `C4` | | `C4 + P1` |
| `γ4` | `gamma4` | `C4 + n1½` |
| `D4` | | `C4 + M2` |
| `δ4` | `delta4` | `C4 + n2½` |
| `E4` | | `C4 + M3` |
| `F4` | | `C4 + P4` |
| `ζ4` | `zeta4` | `C4 + n4½` |
| `G4` | | `C4 + P5` |
| `η4` | `eta4` | `C4 + n5½` |
| `a4` | | `C4 + M6` |
| `α4` | `alpha4` | `C4 + n6½` |
| `β4` | `beta4` | `C4 + n7½` |
| `C5` | | `C4 + P8` |
When stacked against the semioctave the fifth spans a dodecatonal scale with ten large steps and two small steps inside the octave (10L 2s "soft-jaric" a.k.a. "jaramechromic").

The scale is nominated such that the Greek nominals form the Ionian mode starting from the semioctave. The nominals themselves follow their Latin counterparts: Alpha comes after A, beta comes after B, gamma after C, etc..

| Nominal | ASCII | Meaning | Cents from C4 |
| ------- | -------- | ----------- | ------------- |
| `C4` | | `C4 + P1` | `0.000` |
| `γ4` | `gamma4` | `C4 + n1½` | `101.955` |
| `D4` | | `C4 + M2` | `203.910` |
| `δ4` | `delta4` | `C4 + n2½` | `305.865` |
| `E4` | | `C4 + M3` | `407.820` |
| `F4` | | `C4 + P4` | `498.045` |
| `ζ4` | `zeta4` | `C4 + n4½` | `600.000` |
| `G4` | | `C4 + P5` | `701.955` |
| `η4` | `eta4` | `C4 + n5½` | `803.910` |
| `A4` | | `C4 + M6` | `905.865` |
| `α4` | `alpha4` | `C4 + n6½` | `1007.820` |
| `β4` | `beta4` | `C4 + n7½` | `1098.045` |
| `C5` | | `C4 + P8` | `1200.000` |

Notice how the notation is half-way antisymmteric w.r.t. Latin and Greek nominals and how `B4` is missing. The final Greek nominal `ε4` (`epsilon4`) equal to `C4 + n3½` is also left out, but defined to complete the Ionian mode. Some temperaments stretch the scale to make room for both so e.g. 14-tone equal temperament can be fully notated with alternating Latin and Greek nominals.

By their construction the 12 nominals in the table above correspond to each of the 12-tones in 12-TET. The 12 nominals are also well-suited for 22-tone equal temperament.

The accidentals associated with this bihexatonic scale are `r` and `p`.

| Accidental | Monzo | Size in cents | Mnemonics |
Expand All @@ -316,16 +321,16 @@ The accidentals associated with this bihexatonic scale are `r` and `p`.
Tone-splitter and decanominals are associated with the `t` flavor of commas e.g. `17/12` may be spelled `ζ4^17t` (assuming `C4 = 1/1`).

### The interordinal semifourth
When combined with neutral inflections the true tone-splitters induce the notation `m2.5` for the semifourth `P4 % 2` basically for free.
When combined with a semiaugmented unison the true tone-splitters induce the notation `m2.5` for the semifourth `P4 / 2` basically for free.

Notable semiquartal intervals include:
| Name | Logarithmic | Linear | Size in cents |
| -------------------------- | ----------------- | -------------- | ------------- |
| Minor second-and-a-halfth | `m2½`, `P4 % 2` | `sqrt(4/3)` | `249.022` |
| Minor third-and-a-halfth | `m3½`, `M6 % 2` | `sqrt(27/16)` | `452.933` |
| Minor second-and-a-halfth | `m2½`, `P4 / 2` | `sqrt(4/3)` | `249.022` |
| Minor third-and-a-halfth | `m3½`, `M6 / 2` | `sqrt(27/16)` | `452.933` |
| Minor fifth-and-a-halfth | `m5½`, `P4 * 3/2` | `sqrt(64/27) ` | `747.067` |
| Minor sixth-and-a-halfth | `m6½`, `P12 % 2` | `sqrt(3)` | `950.978` |
| Major seventh-and-a-halfth | `M7½`, `M14 % 2` | `sqrt(243/64)` | `1154.888` |
| Minor sixth-and-a-halfth | `m6½`, `P12 / 2` | `sqrt(3)` | `950.978` |
| Major seventh-and-a-halfth | `M7½`, `M14 / 2` | `sqrt(243/64)` | `1154.888` |

### Absolute semifourth pentanominal notation
The split fourth spans a pentatonic (4L 1s "manual") scale:
Expand Down Expand Up @@ -374,14 +379,14 @@ Due to technical reasons the accidentals for the 5L 4s scale, *scarab* (`¤`) an

Semiquartals are associated with the `q` comma flavor e.g. `7/6` can be spelled `φ4^7q` (assuming `C4 = 1/1`).

#### Quarter-augmented Pythagorean notation
### Quarter-augmented Pythagorean notation
As previously mentioned the fifth spans 4 degrees so we can split it again without breaking the ordinal notation.

It does require an intermediary quality between major and neutral called _semimajor_ and correspondingly between neutral and minor called _semiminor_.

The quarter fifth `P5 % 4` is a semimajor second `sM2` (or `½M2`).
The quarter fifth `P5 / 4` is a semimajor second `sM2` (or `½M2`).

The new augmented qualities are quarter-augmented (`qa`, `¼A`) and quarter-diminished (`qd`, `¼d`). Quarter-augmented plus semiaugmented is sesqui-semiaugmented (`Qa`, `¾A`) and correspondingly sesqui-semidiminished (`Qd`, `¾d`).
The new augmented qualities are quarter-augmented (`qa`, `¼a`) and quarter-diminished (`qd`, `¼d`). Quarter-augmented plus semiaugmented is sesqui-semiaugmented (`Qa`, `¾a`) and correspondingly sesqui-semidiminished (`Qd`, `¾d`).

| Accidental | Monzo | Size in cents |
| ---------------------- | -------------- | ------------- |
Expand All @@ -398,7 +403,8 @@ You may encounter them when splitting Pythagorean intervals like the *third-majo

You can even make interordinals like the *quarter-minor sesquith* `qm1.5` by splitting the fifth eight ways `P5 / 8`.

Absolute notation works too `C4 + M6 / 5` happens to be *Dee fifth-flat four* `D⅕♭4`.
Absolute notation works too `C4 + M6 / 5` happens to be *D fifth-flat four* `D⅕♭4`.

### Extra comma flavors
Extra commas include extended Helmholtz-Ellis inflections and additional bridges from above irrationals to just intonation.

Expand All @@ -410,9 +416,9 @@ Pitch can be declared as a period of oscillation, but it's coearced to Hz to pre
E.g. `C4 = 10ms` has the same effect as `C4 = 100 Hz`.

### Obscure types
| Type | Literal | Meaning |
| ------ | ------- | ------- |
| Second | `1s` | Inverse of `1Hz` i.e. `1s * 1Hz` evaluates to `1` |
| Type | Literal | Meaning |
| ------ | ------- | ------------------------------------------------------ |
| Second | `1s` | Inverse of `1Hz` i.e. `1s * 1Hz` evaluates to `1` |
| Jorp | `` | Geometric inverse of `c` i.e. `` is equal to `<1200]` |

### Obscure operations
Expand Down Expand Up @@ -442,3 +448,6 @@ Although the real *raison d'être* is to complete the [Triangle of Power](https:

## Future work
The syntax could be extended to cover movement in time i.e. to become a full textual music notation vis-à-vis Xenpaper.

## Next steps
Check out the [examples](https://github.com/xenharmonic-devs/sonic-weave/tree/main/examples) and [technical documentation](https://github.com/xenharmonic-devs/sonic-weave/blob/main/documentation/technical.md).
6 changes: 6 additions & 0 deletions documentation/intermediate-dsl.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,12 @@ The expression `foo() lest bar()` executes `foo()` and returns the result if it

In `foo() lest bar() lest baz()` execution proceeds from left to right until an operand evaluates successfully. If all fail, the exception from `baz()` is thrown.

It's the inline version of `try..catch`.
```javascript
fraction(P5) lest P5 // Successfully evaluates to 3/2
fraction(PI) lest PI // Falls back to 3.141592653589793r
```

#### Coalescing
| Name | Example | Result |
| ------------------ | ------------- | ------ |
Expand Down
4 changes: 4 additions & 0 deletions documentation/technical.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,7 @@ TODO: For and while loops
## TODO

TODO: Other technical notes

## Next steps

The standard library of SonicWeave is written in SonicWeave. Check out the [prelude](https://github.com/xenharmonic-devs/sonic-weave/blob/main/src/stdlib/prelude.ts).

0 comments on commit 1140790

Please sign in to comment.