This is probably easy enough to explain but
Pkey(\foo, 1).asStream // -> a Routine
Pkey(\foo).asStream // -> a FuncStream
it’s not obvious how that “magic” happens just from Pkey’s source code:
Pkey : Pattern {
var <>key, <>repeats;
*new { |key, repeats|
^super.newCopyArgs(key, repeats)
}
storeArgs { ^[key, repeats] }
asStream {
var keystream = key.asStream;
// avoid creating a routine
var stream = FuncStream({ |inevent| inevent !? { inevent[keystream.next(inevent)] } });
^if(repeats.isNil) { stream } { stream.fin(repeats) }
}
embedInStream { |inval|
var outval, keystream = key.asStream;
(repeats.value(inval) ?? { inf }).do {
outval = inval[keystream.next(inval)];
if(outval.isNil) { ^inval };
inval = outval.yield;
};
^inval
}
}
I mean
Pkey(\foo).asStream // -> a FuncStream
is obvious because there’s an implementation in Pkey that does that special handling. But how comes Pkey(\foo, 1).asStream
still returns a Routine?
N.B. you actually need the 2nd form in some cases, in particular within Pseqs
r = (Pbind(\bar, Pseq([Pkey(\foo) + 1, 22])) <> (foo: 3)).asStream
r.nextN(3, ()) // never gets to 22
// fixy
r = (Pbind(\bar, Pseq([Pkey(\foo, 1) + 1, 22])) <> (foo: 3)).asStream