25. Stream
Stream : value들의 a lazy sequence로서 다음 값은 어떤 message를 보냄으로 받을 수 있기 때문에 lazy란 이름이 붙는다. sequence가 시작되고 reset되고 멈추는것도 message를 통해서 이루어진다. stream의 길이나 규모는 한정적이거나 무한할 수 있고, 한정적일때, stream이 끝나면 nil이 된다.
Stream and its subclasses
math등을 stream에 실행하거나 filtering 할수 있는 class가 있다.
일반적으로 FuncStream이 쓰이는데, 이는 next, reset등의 메세지에 의해서 실행된다.
(
var a;
a = FuncStream.new({ #[1, 2, 3, 4].choose });
5.do({ a.next.postln; }); // print 5 values from the stream
)
또 다른 예제로는 Routine이 있다. Routine은 중간에서 어떤 값을 보내서나 어떤 시점에서 resume될 수 있다. ‘yield’메세지가 Routine으로 부터 값을 부르게 하고, 값은 Routine 이 다시 시작될때, 멈추었던 시점에서 다시 시작한다.
(
var a;
a = Routine.new({
3.do({ arg i; i.yield; })
});
4.do({ a.next.postln; }); // print 4 values from stream
)
(
var a;
a = Routine.new({
3.do({ arg i;
(i+1).do({ arg j; j.yield; })
})
});
8.do({ a.next.postln; }); // print 8 values from stream
)
Math on Streams
(
var a, b;
// a is a stream that counts from 0 to 9
a = Routine.new({
10.do({ arg i; i.yield; })
});
b = a.squared; // stream b is a square of the stream a
12.do({ b.next.postln; });
)
(
var a, b;
// a is a stream that counts from 0 to 9
a = Routine.new({
10.do({ arg i; i.yield; })
});
b = a + 100; // add a constant value to stream a
12.do({ b.next.postln; });
)
(
var a, b, c;
// a is a stream that counts from 0 to 9
a = Routine.new({
10.do({ arg i; i.yield; })
});
// b is a stream that counts from 100 to 280 by 20
b = Routine.new({
forBy (100,280,20, { arg i; i.yield })
});
c = a + b; // add streams a and b
12.do({ c.next.postln; });
)
Filtering on streams
.collect, .select, .reject의 메세지를 사용하여 값을 추출해낼 수 있다.
(
var a, b;
// a is a stream that counts from 0 to 9
a = Routine.new({
10.do({ arg i; i.yield; })
});
// b is a stream that adds 100 to even values
b = a.collect({ arg item; if (item.even, { item + 100 },{ item }); });
6.do({ b.next.postln; });
)
(
var a, b;
// a is a stream that counts from 0 to 9
a = Routine.new({
10.do({ arg i; i.yield; })
});
// b is a stream that only returns the odd values from stream a
b = a.select({ arg item; item.odd; });
6.do({ b.next.postln; });
)
(
var a, b;
// a is a stream that counts from 0 to 9
a = Routine.new({
10.do({ arg i; i.yield; })
});
// b is a stream that only returns the non-odd values from stream a
b = a.reject({ arg item; item.odd; });
6.do({ b.next.postln; });
)
Stream : value들의 a lazy sequence로서 다음 값은 어떤 message를 보냄으로 받을 수 있기 때문에 lazy란 이름이 붙는다. sequence가 시작되고 reset되고 멈추는것도 message를 통해서 이루어진다. stream의 길이나 규모는 한정적이거나 무한할 수 있고, 한정적일때, stream이 끝나면 nil이 된다.
Stream and its subclasses
math등을 stream에 실행하거나 filtering 할수 있는 class가 있다.
일반적으로 FuncStream이 쓰이는데, 이는 next, reset등의 메세지에 의해서 실행된다.
(
var a;
a = FuncStream.new({ #[1, 2, 3, 4].choose });
5.do({ a.next.postln; }); // print 5 values from the stream
)
또 다른 예제로는 Routine이 있다. Routine은 중간에서 어떤 값을 보내서나 어떤 시점에서 resume될 수 있다. ‘yield’메세지가 Routine으로 부터 값을 부르게 하고, 값은 Routine 이 다시 시작될때, 멈추었던 시점에서 다시 시작한다.
(
var a;
a = Routine.new({
3.do({ arg i; i.yield; })
});
4.do({ a.next.postln; }); // print 4 values from stream
)
(
var a;
a = Routine.new({
3.do({ arg i;
(i+1).do({ arg j; j.yield; })
})
});
8.do({ a.next.postln; }); // print 8 values from stream
)
Math on Streams
(
var a, b;
// a is a stream that counts from 0 to 9
a = Routine.new({
10.do({ arg i; i.yield; })
});
b = a.squared; // stream b is a square of the stream a
12.do({ b.next.postln; });
)
(
var a, b;
// a is a stream that counts from 0 to 9
a = Routine.new({
10.do({ arg i; i.yield; })
});
b = a + 100; // add a constant value to stream a
12.do({ b.next.postln; });
)
(
var a, b, c;
// a is a stream that counts from 0 to 9
a = Routine.new({
10.do({ arg i; i.yield; })
});
// b is a stream that counts from 100 to 280 by 20
b = Routine.new({
forBy (100,280,20, { arg i; i.yield })
});
c = a + b; // add streams a and b
12.do({ c.next.postln; });
)
Filtering on streams
.collect, .select, .reject의 메세지를 사용하여 값을 추출해낼 수 있다.
(
var a, b;
// a is a stream that counts from 0 to 9
a = Routine.new({
10.do({ arg i; i.yield; })
});
// b is a stream that adds 100 to even values
b = a.collect({ arg item; if (item.even, { item + 100 },{ item }); });
6.do({ b.next.postln; });
)
(
var a, b;
// a is a stream that counts from 0 to 9
a = Routine.new({
10.do({ arg i; i.yield; })
});
// b is a stream that only returns the odd values from stream a
b = a.select({ arg item; item.odd; });
6.do({ b.next.postln; });
)
(
var a, b;
// a is a stream that counts from 0 to 9
a = Routine.new({
10.do({ arg i; i.yield; })
});
// b is a stream that only returns the non-odd values from stream a
b = a.reject({ arg item; item.odd; });
6.do({ b.next.postln; });
)
reference : SC3 메뉴얼