4. Naming things
▶ Open in Aratu to hear and change the examples
This table is the heart of this part: for each thing in Aratu, the name it would have in programming, and what it is like.
| In Aratu | In programming terms | Like |
|---|---|---|
melody = | c4 d e f | |
a binding of a name to a value; the value is a sequence of bars | a constant: it does not change while playing; each edit defines it again |
| a line | a circular sequence: when it ends, it starts again | a looping clip in a DAW |
drums { hh = …; bd = … } |
a record or namespace: a map from names to lines | an object (drums.hh) |
bass.reverb.mix = 0.42 |
property assignment on a path through a nested map (part → effect → parameter) | bass.reverb.mix = 0.42 in JavaScript, or a CSS rule |
bass: synth.saw -> lowpass -> reverb |
a pipeline: each one's output is the next one's input | function composition, reverb(lowpass(saw)), or the shell's | |
synth.saw, piano.grand |
a key in a catalogue (an enum): a name that picks a ready-made sound | a value from a fixed list; not a method |
motif riff = [e4 d c d] |
a macro: the name is replaced by its content wherever it appears | a function without side effects, expanded in place (inlining) |
riff+2, riff+3st |
the motif with an argument: the transposition | riff(2) |
riff.inv, riff.retro, serie.P5 |
a pure transformation written with a dot: it returns a new motif and leaves the original alone | a method or computed property without parentheses |
row serie = 0 11 3 4 … |
a vector (array) of whole numbers from 0 to 11 | [0, 11, 3, 4, …] |
| o o o o | from serie.P0 |
a zip of the rhythm with the vector, starting it again when it runs out; each o is a placeholder to fill |
zip(rhythm, cycle(row)) |
list temas { … } |
an array of melodies, counted from 1 | temas[1] in JavaScript is temas.2 in Aratu |
temas.all, temas.random |
concatenation; a random choice of one item | temas.flat(), temas[random()] |
{c|g} |
a random choice, drawn each time round | random.choice |
c?30% |
an event with a 30% probability | if (random() < 0.3) |
seed 7 |
the seed of the pseudo-random generator: the same seed gives the same result | Random(7) |
pattern groove { … } |
a named block of lines | a component, a scene, a template |
play groove x3, fill |
a playlist: a sequence with repeats, looping | a list of scenes |
|: :|, %, D.S. al coda |
the score's jumps, resolved before playing | a goto the compiler unrolls |
[e4 d]x4, riffx4 |
unrolled repetition: it becomes four copies | loop unrolling |
p:, mf: |
a state that holds for the following notes of the line | the "current colour" in a drawing library |
300 Hz -> 4000 Hz over 4 bars |
interpolation of a value over time (on a logarithmic scale for frequencies) | a tween, keyframe automation |
| a knob | a two-way binding: turning it rewrites the number in the text | the text stays the source of truth |
Is at bar a switch?
Not quite. A switch (or case) picks one path among several, each time
it runs, by a value. An at bar is a rule indexed by time: from bar 9
on, it holds, and it keeps holding until another rule changes the same
thing. It is closer to a keyframe in an animation, or an event marked on
a timeline.
tempo: 110
bass = | c2 _ g1 _ |
at bar 5: bass.reverb.mix = 0.6
at bar 9: bass: outTo know the state at bar 12, Aratu gathers the rules of every bar up to
there: the reverb is at 0.6 (since bar 5) and the bass is out (since bar 9).
In programming, that is a fold of the changes, in time order.
from bar 9 to 16: is a rule with a start and an end: outside its stretch
it stays out of the fold, and what came before holds again.
every, on the other hand, is the nearest thing to an if on the bar
number:
tempo: 110
pattern groove { hh = cc cc cc cc; bd = b - b -; sd = - s - s }
pattern fill { sd = ss ss SS SS }
play groove
every 4 bars: play fillevery 4 bars: play fill means, bar by bar, "if this is the last of every
four, play the fill instead": if (bar % 4 == 0). And every 4 bars, first:
is if (bar % 4 == 1).