jdonaldson / promhx

A promise and functional reactive programming library for Haxe
MIT License
145 stars 24 forks source link

stream.first() method name is misleading #49

Open mcheshkov opened 9 years ago

mcheshkov commented 9 years ago

stream.first() actually return promise not to "first value stream will resolve to after this call" but to "last value stream resolved to, or first one if it never resolved" - that's quite confusing. Blame isResolved branch of immediateLinkUpdate. Is it by design?

jdonaldson commented 9 years ago

Yes, that's not as clear, it should be called "next" or something. I'll deprecate "first" in favor of "next", and drop it on the next major version.

mcheshkov commented 9 years ago

You mean with "next after call" or with current semantic?

jdonaldson commented 9 years ago

I can give the rationale for this: You can use a promise in place of a stream as-is. It'll only resolve once, but that's just fine for a stream. However, the other way around doesn't work... a stream can resolve multiple times, but a promise can only resolve once. So, that method only takes the first resolving value. However, the "first" resolving value is not in reference to the async that is providing the value, but rather the other code calling it.

After thinking about it, calling this method "next" is confusing as well, partly for the reasons you say: Such a function would resolve the currently resolved value (if it's resolved), and not the next actual value. It all would depend on whether the value was resolved or not. "next" is also confusing because it doesn't give the same clarity that only one value is resolved (i.e., that the return value is a promise and not a stream).

I could add a separate "next" function for what you want, but now I have to wonder... is something like that better handled with "filter"? What kind of use case are you looking at?

mcheshkov commented 9 years ago

I've hit this with following case. It's quite dirty.

Socket (or any other byte stream IPC), messages over that socket. Stream. Now I want to model Request-Response over that. But protocol (which is legacy, and I can't control) is not strictly request-response, sometimes there can be multiple responses. So I'm using stream to model anything received, control request issuing (no pipelining etc.) and for parts that are request-response I'm using method with semantic I've described.

jdonaldson commented 9 years ago

sorry for the delay.

It sounds like stream is really what you want. You can manage a custom promise resolve in there according to whatever logic you wish.

In the next version, I'm thinking of calling this current method "firstAvailable". It will take the current value if it's already set, or it will wait for the next update if not. Does that make sense?

I don't really see how I can handle your case otherwise, what would you propose?