--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Stream
A “Stream” is an object that emits a (possibly non-terminating) sequence of events. In the IO library, these are mainly data events, represented as byte-arrays, whereas for the isolate library the data is most often lists, maps, Strings, numbers and booleans.
The main thing one does with a stream is subscribe to it, calling the method “subscribe” with optional arguments onData, onError, and onDone.
class Stream<T> {
StreamSubscription<T> subscribe(
{void onData(T data),
void onError(AsyncError error),
void onDone(),
bool unsubscribeOnError});
...
}
Ignoring corner-cases, and in particular error-handling, this method basically subscribes to the stream and will then receive all events.
Example:
new File('/etc/passwd').openForRead() // returns a Stream.
.subscribe(onData: (List<int> data) { print(data.length); });
--
Dear dartisans,
TL;DR: please play with our Stream-based IO and isolates and give us feedback. See instructions near the end of the mail.
As announced some weeks ago, we have continued our library refactoring in an experimental branch to avoid unnecessary breakages. We have now reached a small milestone in our development, and would like to invite the community to play with the current library and give us some feedback.
Milestone “streams”: users have been asking for a simpler asynchronous library, where everything works in a consistent way, for some time now (see for example http://goo.gl/cWaJh for Sean Seagan’s proposal). With this milestone we finally have running code that gets us one step closer to that goal. We have now converted both the IO library and isolates to use our new class for repeating events, Streams. Both are currently only wrapping the old primitives, but eventually we want to remove support for the old API. The html library is not yet adapted but should eventually also use streams for UI events.
We have also improved the Future class, and made it simpler to use. One simple “then” methods lets you apply asynchronous or synchronous functions to the result of a future, merging the three methods “chain”, “transform” and “then”.
--
I love that streams are called Streams (instead of Observables, that's a horrible name) and I believe that this should go into dart:core. Async is central to Dart. The analogy with Iterables works great.
But there is one thing that I hate about almost all reactive frameworks, this one included -- their push-based nature. For me, inversion of control doesn't really work here. Maybe it's just me, but I always have a hard time thinking about such code. And you practically _have to_ have all these combinators like mappedTo, where or reduce, because you _can't_ use all the language features that you have (if, while, for), not even speaking about exceptions.
I wanted to try to prototype a pull-based (or at least looking-like-pull-based) reactive framework, but I have two other interesting projects in the work right now, so... :-(
And a little bit of mandatory bike shedding: I don't like the naming of Stream/Sink/StreamController. It took me quite a while to realize that Sink (which I thought would be something where the stream ends) is actually a beginning of the stream. StreamSource, maybe? And StreamController is actually a Stream and its source together... more like WritableStream or something.
LT
P.S.: huge thanks for this email, it made me understand a lot better than looking at the code!
I love that streams are called Streams (instead of Observables, that's a horrible name) and I believe that this should go into dart:core. Async is central to Dart. The analogy with Iterables works great.
But there is one thing that I hate about almost all reactive frameworks, this one included -- their push-based nature. For me, inversion of control doesn't really work here. Maybe it's just me, but I always have a hard time thinking about such code. And you practically _have to_ have all these combinators like mappedTo, where or reduce, because you _can't_ use all the language features that you have (if, while, for), not even speaking about exceptions.
I wanted to try to prototype a pull-based (or at least looking-like-pull-based) reactive framework, but I have two other interesting projects in the work right now, so... :-(
And a little bit of mandatory bike shedding: I don't like the naming of Stream/Sink/StreamController. It took me quite a while to realize that Sink (which I thought would be something where the stream ends) is actually a beginning of the stream. StreamSource, maybe? And StreamController is actually a Stream and its source together... more like WritableStream or something.
LT
P.S.: huge thanks for this email, it made me understand a lot better than looking at the code!
--
I wanted to try to prototype a pull-based (or at least looking-like-pull-based) reactive framework, but I have two other interesting projects in the work right now, so... :-(
Conal Elliot tried something along these lines (http://conal.net/papers/push-pull-frp/) and blogged later that he was struggling with serious performance problems. I don't know what's the current status. But anyway in his implementation the API doesn't change, which seems to be your main concern. How would the API you're thinking of look (roughly)? My understanding was that Dart lacks the basic primitives to re-invert the control.
LT
I wanted to try to implement something like the code in chapter 3 of the Deprecating the Observer Pattern paper (http://lampwww.epfl.ch/~imaier/pub/DeprecatingObserversTR2010.pdf), at least to find how natural would it look like in Dart.
I was about to cite that one :) But I think the trick of this paper (if I remember correctly) is that it relies on delimited continuations to re-invert control. And that's exactly what Dart misses (on purpose since it's not clear how to compile them to efficient Javascript).
On Tue, Nov 27, 2012 at 9:08 PM, Florian Loitsch <floi...@google.com> wrote:
> Note that, contrary to how C# acts, Dart iterators don’t throw when accessedI wonder what the motivation for this is. It seems like it's
> out of bounds.
>
> Example:
> var it = [1, 2].iterator;
> while(it.moveNext()) {
> print(it.current); // 1, 2
> }
> print(it.current); // null.
analogous to an out-of-bounds array access, which throws rather than
just returning null.
--
Erik Corry, Software Engineer
Google Denmark ApS - Frederiksborggade 20B, 1 sal,
1360 København K - Denmark - CVR nr. 28 86 69 84
I wanted to try to implement something like the code in chapter 3 of the Deprecating the Observer Pattern paper (http://lampwww.epfl.ch/~imaier/pub/DeprecatingObserversTR2010.pdf), at least to find how natural would it look like in Dart.
I was about to cite that one :) But I think the trick of this paper (if I remember correctly) is that it relies on delimited continuations to re-invert control. And that's exactly what Dart misses (on purpose since it's not clear how to compile them to efficient Javascript).
I didn't look at the code for that, but if I understand correctly, they throw continuations in the basket only in later stages.
I wanted to stick to the basic pull-based model of chapter 3 and I thought I'd be able to implement that in Dart just fine. Maybe I'm mistaken, can't know until I get my feet wet.
LT
--
LT
P.S.: huge thanks for this email, it made me understand a lot better than looking at the code!
--
I'd star that. There's one thing that would need to be cleared up in the proposal, though.So if you have on and you have await, you could do something like:async asyncFunc1(Stream stream) {on(var x in stream) {y = await x.asyncFunc2();// ... Can the next iteration of this loop begin before this code is executed?}}So... The simple way to implement the behavior of "on" would allow for either the second iteration of the loop to begin or the first iteration (after await) to finish, depending on whichever event happened first. And that may be more efficient, but it's also more complicated to think about; the beauty of "await" is that the code looks and acts like sequential code, except that can be interrupted at the awaits.