7.10.3. STRUDEL-03 — Mini-Notation Advanced

The four operators in this tutorial — <...>, @N, ?, and !N — are what take you from drum-machine patterns to genuinely musical phrases. They also exist purely inside the mini-notation parser: each one rewrites the parsed pattern into the same combinators (cat, weighted_fastcat, degrade, fast) you can call directly from daslang. Knowing both forms is useful: mini-notation for terseness, combinators when the input is dynamic.

7.10.3.1. Part A: Alternation with < >

Angle brackets pick one element per cycle, advancing on each cycle and looping when it runs out:

let pat <- s("<bd sd cp>")
play(pat, 6.0)

You hear bd on cycle 0, sd on cycle 1, cp on cycle 2, then back to bd. This is the cat combinator under the hood: the angle group spans one full cycle each iteration.

Inside a sequence the angle group still occupies one slot:

let pat <- s("bd <sd cp> hh hh")
play(pat, 4.0)

The <sd cp> slot alternates each cycle — snare on cycle 0, clap on cycle 1. This pattern is how you write “second beat changes” in a single line.

7.10.3.2. Part B: Elongation with @N

Postfix @N makes an element occupy N units of the parent sequence (default is 1). It is implemented via weighted_fastcat — the parser tracks weights for each token and divides the cycle proportionally:

let pat <- s("bd@3 sd") |> sustain(0.5)
play(pat, 4.0)

Without @3 each token would get half a cycle. With it the kick gets 3/4 and the snare gets 1/4. This is how you write swung or front-loaded phrases without nested brackets.

Underscore _ is the equivalent for the previous element: "bd _ _ sd" is the same as "bd@3 sd". Use whichever reads better for your phrase.

7.10.3.3. Part C: Degrade with ?

Postfix ? randomly drops events at the marked element with 50% probability. Hi-hats are the canonical use:

let pat <- s("bd hh? sd hh?")
play(pat, 6.0)

The kick and snare are reliable; the hats appear roughly half the time, randomly per cycle. Run it twice and you get different results — the RNG seed is tied to the cycle position so the rhythm is deterministic within one play, but the pattern feels human.

You can also write hh?0.25 to use a different drop probability — the default ? is shorthand for ?0.5.

7.10.3.4. Part D: Replicate with !N

Postfix !N is like *N from tutorial 02 but expands the element into N parent slots instead of squeezing them into one:

let pat <- s("bd!3 sd")
play(pat, 4.0)

This expands to four equal slots bd bd bd sd — three kicks then a snare. Compare to bd*3 sd which packs three kicks into one slot followed by a snare in the second.

The mental model: *N divides time, !N adds slots. Use * to make things faster within one slot, ! to repeat the same element across the parent sequence.

7.10.3.5. Where next

You now know the full mini-notation surface. Tutorial 04 leaves the parser behind and shows the time algebrafast, slow, rev, hurry — which transforms any Pattern (mini-notation or not) by rewriting query spans.

See also

Full source: tutorials/daStrudel/daStrudel_03_mini_notation_advanced.das

Previous tutorial: STRUDEL-02 — Mini-Notation Fundamentals

Next tutorial: STRUDEL-04 — Time Manipulation

Related: Random Numbers — how degrade’s randomness is seeded