paldepind / flyd

The minimalistic but powerful, modular, functional reactive programming library in JavaScript.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Passing stream to another stream?

dmitriz opened this issue · comments

I have been playing with flyd and really liked how a promise p can be passed directly to a stream s as s(p), and the "promised" resolved value will simply appear in the stream:

However, when I pass another stream s1 to s the same way - s(s1), the stream s instead emits the string representation of the function implementing s1. That seems unfortunate.

Philosophically, I would regard a promise as a special stream which emits the resolved value (or the error). So it would seem natural to have s(s1) behaving along the same line, i.e. s getting all the emitted values from s1. Would that make sense?

Amusingly, that behaviour can be obtained via s1.map(s), where s acts like a function, but the other syntax s(s1) would be terser and more elegant, perhaps, and in line with the promises.

Would be curious to hear other opinions.

Hello @dmitriz.

I think the way you do this with map is neat. I hadn't thought of doing it like that. Alternatively, one might use on instead of map like this s1.on(s).

I agree that emitting the string representation of the function is unfortunate. But, while I think think the behavior you're suggesting is interesting, I must admit that I find it a bit too implicit. To me s(s1) reads as "send the value s1 into s". I think s1.on(s) communicates better that the intention is to call s with all values from s1. And the difference in code size is minimal so I'd prefer the more explicit version.

What do you think?

Many thanks @paldepind for taking your time to comment!

To me s(s1) reads as "send the value s1 into s".

That is exactly my intuition and was the very reason for this proposal
and the proposed functionality:

After s(s1) is executed, if s1 emits val, it is sent into s,
so s would emit val too. Isn't that also what you mean?

I must admit that I find it a bit too implicit.

May I ask why? Can it be misunderstood?

I agree that emitting the string representation of the function is unfortunate.

Glad we agree on that ;)
The current behaviour seems to be against our intuition of sending s1 values into s
(string rep. of function is not a value).

I think s1.on(s) communicates better that the intention is to call s with all values from s1.

To me .on reads like event handler, with s getting confused for an event and the whole construct is like a partial function expecting some sort of even handler. So I would feel confused, but it may be just me.

Also that would duplicate the already provided functionality of map.

I would find it good to have both syntaxes s(s1) and s1.map(s), each having their pros and cons. That also seems to be in line with how map generally behaves.

I find unifying concepts under common abstraction a great way of reducing code complexity, and your idea of putting streams under the same hat with functions really neatly serving that purpose. It is probably the most interesting and unique feature of flyd, making it stand out among other stream libraries. I should thank @JAForbes for calling my attention to it, as it is somehow was not evident to me from the intro. It should be great to bring it to the next level by extending this behavioural uniformity.

Let me know if that makes sense.

@paldepind I think this can be closed since we've removed Promise swallowing