This is not actually a totally awful way of doing this - there is a LOT of subtlety to how
Pdef incorporates changes to a playing pattern (e.g. using
quant to change on beat, etc) - if you want a sort of Ableton Live style hot swapping of patterns, this is a straightforward way to take advantage of all that subtle playback stuff. The code is simple and comprehensible, and does what it looks like it does, which is never bad.
However, there are many other ways to do this as well - here are some suggestions, maybe one of these is a better fit for your workflow. I had to modify your patterns slightly in some cases, because a few things (e.g. a series with a pattern as it’s
length parameter) are tricky and would confused the example
 Pull parameters from Pdefn’s
This is nice b/c you can then use patterns in place of fixed values for each Pdef, which becomes compositionally very powerful - and you can set individual
quant values for each parameter, which is cool.
) * 1 / Pdefn(\steps),
Pseries(0, Pdefn(\steps), 4).repeat
 Compose with another event stream
Similar to , but stick all your params in one event stream and access via Pkey. This is better if you want a parameter to change to be applied “all at once”, and (for me) the code is a little clearer.
) * 1 / Pkey(\steps),
\degree, Pseries(0, Pkey(\steps), 4).repeat,
) <> Pdef(\params)).play;
 Use a function in your Pdef
Some of your original code is hard to reproduce entirely with patterns (e.g. some parameters expect numbers and not streams), so “building” the entire thing in a function is still easier. Pdefs with a function will pull that functions arguments from whatever the incoming event is, so you can compose it with
Pdef(\params) (as in ) to fill them in.
the function is only called when the pattern inside it has run out of events - if it’s repeating infinitely, it won’t ever reset. This can be an advantage because it means you have coherent phrases, and parameters won’t be changed until the end of the phrase… So basically, make your inner Pdef pattern finite, and then if you want to repeat it, repeat it where you use it (with
numBeats - I think the
beats key has special meaning and can get obliterated in some cases? I didn’t track down exactly where…
\bass into a
Pmono - if the
Pmono is inside of the function, then your note basically gets reset every time that function is called (a new Pmono is created) - this may be desirable behavior, or maybe not…
There’s nice thing I do sometimes where you can wrap the pattern in
\bass in a
Pfindur, which means it will play an exact amount of time, and then finish - then, you can do really complex poly-rhythm stuff, but the pattern and it’s parameters are always reset at at predictable metric, so it doesn’t turn into algorithmic soup.
You can use events of
type: phrase to do almost exactly what I’m doing in this example. This gives you some nice things “for free”, but is also less flexible and less obvious - look at the help for recursive phrasing for more info.
|steps=8, numBeats=3, offset=0, size=4, grow=1|
[steps, numBeats, offset, size, grow].postln;
\dur, Pbjorklund2(numBeats, steps, offset: offset) * 1 / steps,
\degree, Pfin(numBeats, Pseq(Array.series(size, 0, grow)), inf).repeat(4),
Pdef(\player, Pmono(\default) <> (Pdef(\bass) <> Pdef(\params)).cyc).play;