The reason it doesn’t work (I run into this gotcha regularly, and constantly have to remind myself…):
When you’re next-ing a pattern in a Pbind
to get some kind of result, if you encounter another pattern, in general that pattern is immediately embedded. By embedded, I mean It effectively takes over returning values until it’s run out (at which point control falls back to outer pattern). So, in a case like:
Pseq([0, 1, 2, Pseq([3, 3, 3]), 4]);
you’ll get: 0, 1, 2, 3, 3, 3, 4
, because when the nested Pseq is reached, it returns values until it runs out.
This is a particular gotcha with Pfunc
because unlike most patterns, a basic Pfunc
will usually return values forever (I believe until you explicitly return nil
?). For most pattern types, encountering a nested Pfunc
results in it being embedded, and then returning values forever and never returning control to e,g. the outer Pseq
.
Pfuncn
works because it has an extra argument specifying how many values it will return when it’s embedded - and the default is 1. The pattern class that behaves more in line with your intuitions is probably Ppatlace
- this is similar to a Pseq
- but if it encounters a nested pattern, it returns one value, holds on to the state of that pattern, and then moves on to the next. So you get:
Pseq([ Pseq([1, 2, 3]), Pseq([4, 5, 6]) ]).asStream.all;
-> [ 1, 2, 3, 4, 5, 6 ]
Ppatlace([ Pseq([1, 2, 3]), Pseq([4, 5, 6]) ], inf).asStream.all;
-> [ 1, 4, 2, 5, 3, 6 ]
Note that I did not specify a number of repeats for Pseq
, because by default it moves through it’s list an exhausts every stream before it finished. With Ppatlace
, repeats specifies how many times it loops through the list - so with the default repeats:1
, you only get two numbers (one for each pattern in the list).