-
-
Save ekozhura/cb682b577a9f86be1fd8 to your computer and use it in GitHub Desktop.
( | |
var a, b; | |
a = Routine.new({ | |
inf.do{ |idx = 1| | |
idx.yield; | |
} | |
}); | |
b = a.collect({|item| item * 2;}); | |
b.nextN(10).postln; // -> [ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 ] | |
a.nextN(10).postln; // -> [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ] WTF?!? | |
) |
@jamshark70 Thanks so much for explanation.
One last question. You mentioned that there's no way to create a copy of a routine object. So what really happened when I use shallowCopy
method? In this example a
isn't affected
(
var a, b;
a = Routine.new({
inf.do{ |idx = 1|
idx.yield;
}
});
b = a.shallowCopy.collect({|item| item * 2;});
b.nextN(10).postln; // -> [ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 ]
a.nextN(10).postln; // -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
)
I found an old thread where James McCartney explained a reason of why routines could not be copied.
It would mean copying the entire call stack. Since you can non-local return out of a Routine to the parent thread, it would mean copying the parent thread(s) call stack(s) as well. Otherwise, loop counters, instruction counters, stack pointers, etc would get very confused if a frame were re-entered twice. So multi shot continuations are not easily possible.
sc-dev: strange stream embedding behaviour.
Another observation: shallowCopy
worked in my previous example because b
was created before a
was started. Otherwise shallowCopy
would simply return a reference to a
(at least, it seems so). That also makes sense, considering the quote of James McCartney.
Routines are stateful and -- here's a big part of the key to your problem -- they cannot be copied. For
a.collect
to evaluate, it must get something froma
-- and there is only onea
. There is no way to make a separatea
.The thing you're looking for is a pattern. Patterns are stateless: stream factories. You can nest them, filter them at will and produce any number of independent streams.