Limitations of Pproto stemming from its asArray conversion of the pattern?

I’ve noticed that Pproto does this conversion internally

stream = Pfpar(pattern.asArray).asStream;

I was thinking it would not work if the pattern is a Pfunc, but it still seems to work ok with those… So (what if any) are the usage limitations stemming from this conversion?

(I see James is/was quite unhappy with Pproto in general.)


Pfpar parallelizes multiple patterns. The subpatterns get evaluated individually, and interleaved based on their own deltas.

“Individually” means the next call on the subpattern’s stream is exactly the same as the next call if you played the pattern by itself. (And, if you “play-in-parallel” a single pattern, then there is nothing to interleave, so it behaves exactly like playing it without the wrapper.)

The .asArray is to build the Pproto. Then Pfpar within Pproto takes the array apart again.

So this is a case of looking for a problem where there isn’t one.


Yeah, asArray is a no-op for arrays… Rather basic confusion on my behalf.

1.asArray // [1]
[1, 2].asArray // still [1, 2]

I see from example 4 in the Pproto help that it also want to work as Ppar… well actually end on any sub-stream ending. Speaking of this, frankly I’m not sure that Pproto should really be both a parallel player and a resource management thing. While working on fixing its behavior with the user-supplied cleanup, I’ve discovered a real bug in Pproto, namely that it does a “double free”, well a double “cleanup.exit”, because both Pproto and its Ptpar inner stream do this when the stream ends. I’ve managed to find this bug after fixing the behavior of the user-supplied cleanup, because I was able to pass my own cleanup (printing) function through it…

I’ll post about that user-cleanup fix separately… I’m not sure how (or rather where) to fix the “double cleanup.exit” issue presently though because Ptpar might be useful to call/use independently from Pproto…

My opinion is still that Pproto should be deprecated and rewritten as something else.


I’d be interested to hear more of your thoughts on this. Was it discussed in more details some place I haven’t found yet? I don’t want to spend my time fixing something that’s gonna go away… The basic idea of having a default “garbage collector”, i.e. cleaner for various resource-allocating event types doesn’t strike me as bad since it saves up drudgery on a number of occasions.

My problem with it is not the concept of a pattern with cleanup, and I think the intention (to create something friendly for NRT rendering and real-time play with the same code) is sound. But there are so many implementation mistakes and design limitations that it becomes a real question whether it should be repaired, or junked and redesigned.

I’m not sure which is better / easier. If it’s repaired properly then there wouldn’t be a need to deprecate it.


The problem may be worse than you think, but not necessarily where you think it is… Generalized conceptual design flaw (double free) of cleanups?