Alternating between sub-patterns in fixed order?

Hey all, apologies if this newbie question has already been asked or if I missed it in the documentation.

I am trying to find the best solution to alternate between sub-patterns in a fixed order. Using Pswitch I can get my desired behavior, but every time I add a new subppatern I have to embed the full sequence. Alternatively I can use Prand to get one subpattern at a time, but I lose the fixed order that I am hoping for.

(
var a,b,c,d,e,s;
a = Pseq(0!3,1);
b = Pseq(11!2,1);
c = Pseq(22!2,1);
d = Pseq(33!2,1);
e = Pswitch([a,b,c,d], Pseq([0,1,0,2,0,3],inf));
// e = Pseq([a, Prand([b,c,d],1)],inf); // random order
s = e.asStream;
21.do({
    s.next.postln;
});
);

// 0,0,0,11,11,0,0,0,22,22,0,0,0,33,33,0,0,0,11,11,0...

So, is there some pattern class that can alternate between subpatterns in a fixed order?

e = Pseq([a, P?([b,c,d],1)],inf);
// 0,0,0,11,11,0,0,0,22,22,0,0,0,33,33,0,0,0,11,11,0...

Or is there some other solution I’m missing?

Thanks for the help :slight_smile:

How about this?

(
var pseqs, seqOrder, switch, stream;
pseqs = [
	Pseq(0!3,1),
	Pseq(11!2,1),
	Pseq(22!2,1),
	Pseq(33!2,1)
];
seqOrder = (pseqs.size - 1).collect { |index| [0, index + 1] }.flat;
switch = Pswitch(pseqs, Pseq(seqOrder, inf));
stream = switch.asStream;
21.do { stream.next.postln };
)

Hi and welcome,

You can check out PSstream patterns from miSCellaneous_lib (Quark extension). They behave like streams: embedded and resumed. Your example could be written like this:

(
var a,b,c,d,e,s;
a = Pseq(0!3,1);
b = Pseq(11!2,1);
c = Pseq(22!2,1);
d = Pseq(33!2,1);
e = Pseq([a, PS(Pseq([b, c, d], inf), 2)], inf);

z = e.asStream;
21.do { z.next.postln };
)

BTW: It’s recommended to avoid using the interpreter variable s, by convention s is reserved for the server, some helpfile code would not work after redefining.

best

Daniel

The tricky thing here is that such a pattern class couldn’t be stateless, and pattern classes in general should be stateless (though that border is a bit porous).

“Stateless” is a bit hard to explain briefly, but the effect of statelessness is that every time a given pattern object is used, the stream is completely independent of every other time it’s used. There’s no crosstalk between different occurrences of the same pattern object. This kind of crosstalk would happen if the pattern object itself retained information about a stream’s operation – if the pattern object maintains the stream’s state.

The behavior you want here is: first time encountering this pattern object, embed the first pattern in the list and exit (to let the upper level pattern continue); second time, embed the second pattern and exit; etc. At every “exit,” the pattern object would have to remember where it was. Then it’s no longer stateless. If you embedded the same pattern object in multiple places, each one would advance. You couldn’t have independence between them. You would need multiple pattern objects for that.

Daniel’s PS objects seem to be providing essentially “stateful patterns,” which are fine as long as each instance is used in one place only.

With Pswitch, you’re separating the “which pattern” state from the subpatterns, and it gets the desired behavior without breaking the statelessness contract. I don’t think there’s a way to unify all of that, without breaking the contract.

hjh

I was struggling with the same idea, sequencing patterns without resetting them.
I came up with the following .asStream solution, but I guess this breaks the above mentioned statelessness contract.

(
a = Pseq([Pfin(3, Pseq([1,2,3,4],inf).asStream), Pfin(3, Pseq([10,11,12,13],inf).asStream)], inf).asStream;
a.nextN (12);
)

Returning: [ 1, 2, 3, 10, 11, 12, 4, 1, 2, 13, 10, 11 ].