Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic E.merge #23

Open
art-w opened this issue May 15, 2015 · 2 comments
Open

Dynamic E.merge #23

art-w opened this issue May 15, 2015 · 2 comments

Comments

@art-w
Copy link

art-w commented May 15, 2015

It's currently expensive to merge a dynamic collection of events: The E.merge function only works on a fixed list, so on each change to the list, we need to re-merge it from scratch (and the cost is proportionate to the number of elements in the list, rather than the number of added events.) Alternatively, we can merge the previously merged event with the new ones: This time, we pay a slow down proportionate to the number of updates to the list.

Would it be possible to have an analogue to E.switch, that would compute the "merge" of the inner events efficiently? (rather than their sequencing)

val union : ('a -> 'a -> 'a) -> 'a event -> 'a event event -> 'a event

(* or fold-like, but it looks confusing *)
val union : ('a -> 'b -> 'a) -> 'a -> 'b event -> 'b event event -> 'a event

I personally only care about union f when f is commutative, and I don't believe there's a serious use case for an "ordered dynamic merge", but that's discussable (in practice, the commutative version can be faster -- and the ordered one is recoverable from it.)

@dbuenzli
Copy link
Owner

val union : ('a -> 'a -> 'a) -> 'a event -> 'a event event -> 'a event

If I'm not mistaken, any event occurring on the higher order event can never be gc'd until the resulting event is. So union looks like a combinator to shoot yourself in the foot (aïe) as it's the kind of event you are likely to have at the toplevel of your program and that you never gc.

@art-w
Copy link
Author

art-w commented May 17, 2015

Yeah, I do not have a good proposal for a union that lets you remove events in an explicit way (for the gc.) If union doesn't keep a reference to the inner events, then it's up to the user to keep them alive until they are judged unneeded (I don't think this is very intuitive nor coherent with the rest of React api). If union does keep a ref, then the inner events are indeed un-gc-able; maybe union could forget the stopped events to let them be collected (it might not be cheap if done too aggressively.)

The version that specifies explicitly when to remove an event looks very ugly:

val union : ... -> ('a event * unit event) event -> 'a event

because the "natural" way is to call E.until on the user side, rather than passing the (e, stop_e) explicitly to union.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants