improve snapshotE and filterE

31 views
Skip to first unread message

Zang MingJie

unread,
Nov 18, 2011, 3:56:23 AM11/18/11
to fla...@googlegroups.com
Hi

I don't understand why snapshotE discard the value of EventStream, maybe we can introduce a function to merge the values of E and B. here is the new signature of snapshotE

snapshotE : (EventStream a, f: (a, b) -> c, Behavior b) -> EventStream c

or even more:

snapshotE : (EventStream a, f: (a, b1, b2) -> c, Behavior b1, Behavior b2) -> EventStream c
snapshotE : (EventStream a, f: (a, b1, b2, b3) -> c, Behavior b1, Behavior b2, Behavior b3) -> EventStream c

or generic:

snapshotE : (EventStream a, f: (a, b...) -> c, Behavior b1...) -> EventStream c

and for filterE, I'd like to filter a stream depending another behavior:

// behaviorB : behavior Boolean
sourceE.filter(function (_) {
  return valueNow(behaviorB)
})

but valueNow is evil, and I don't want to use it, and I can implement it use my new snapshot:

sourceE.snapshotE(function (e, b) {
  return [b, e];
}, behaviorB).filterE(function(tuple) {
  return tuple[0];
}).mapE(function(tuple) {
  return tuple[1];
})

Jacob Baskin

unread,
Nov 18, 2011, 8:57:55 AM11/18/11
to fla...@googlegroups.com
I've been of the opinion for awhile that this is just about the biggest gap in the language: the lack of better ways to combine both events and behaviors.

This improved snapshotE is certainly the most common one (I called it CombineEB in Resume/Continue); I'd also like a version of collectE that outputs a behavior instead of an event (we know the starting value after all); and switchBE (Behavior EventStream a -> EventStream a).


Arjun Guha

unread,
Nov 20, 2011, 6:21:57 AM11/20/11
to fla...@googlegroups.com
Absolutely. I actually think event streams and behaviors should be meshed into a single type.

Daniel Bünzli

unread,
Nov 21, 2011, 3:21:03 AM11/21/11
to fla...@googlegroups.com
On 20 November 2011 12:21, Arjun Guha <arjun...@gmail.com> wrote:

> Absolutely. I actually think event streams and behaviors should be meshed
> into a single type.

When I implemented my own frp library I thought about that and didn't
do it in the end. I think the rationale was the following.

You can model an event with a behavior carrying an option type to
indicate event occurrences. However when you have an event you need
two update cycles: to model the signal edge you need to go from None
-> Some v and then back from Some v -> None. If you have events as a
primitive you need only one update cycle.

Now you could say I model an event with a behavior that remembers the
last occurrence of the event. But you can't get rid of the option type
because of initialization (before any event occurred). Thus you have a
None just for the beginning and then you always have a Some after the
first occurrence. However in you code you always need to cope with the
possible None which is annoying and makes the code less readable.

Modeling behaviors as events (the events of its changes) seems less
natural to me, as events have no notion of "current" value and I think
you want that at a certain point. This means that you'll end up using
reference cells but one of the beauty of frp is that it allows you to
get rid of them.

Or were you thinking about something else ?

Best,

Daniel

Shriram Krishnamurthi

unread,
Nov 21, 2011, 7:53:30 AM11/21/11
to fla...@googlegroups.com
Hi Daniel,

Out of curiosity, what did you implement it in? What I mean by that
is, I'm trying to understand to what extent the modeling of events as
behaviors was messy *as a result of a static type system*. This is
not to downplay their value, just to understand the impact. For
instance, if the None-ness "leaked" through the representation, every
use of the event would have to switch on the option type, and that
would be unusable.

Shriram

Daniel Bünzli

unread,
Nov 21, 2011, 11:50:20 AM11/21/11
to fla...@googlegroups.com
Hello Shriram,

First I just want to say that my solution of modeling events with a
behavior that remembers the last occurrence works only if you have
some kind of unique id or timestamp per event occurrence. Since if you
update a behavior with an equal value the dependency graph is not
updated, and thus a sequence of two equal event occurrences will fire
a single update instead of two.

As such I don't find this solution very satisfactory. I'd prefer a
behavior that models event occurrences with an edge None -> Some value
-> None, but again that's not efficient since it fires two updates.

> Out of curiosity, what did you implement it in?

OCaml (it's here [1], the implementation is along the lines of FrTime
with a few changes to accommodate the typed setting).

> What I mean by that
> is, I'm trying to understand to what extent the modeling of events as
> behaviors was messy *as a result of a static type system*.

It may be. I'm not sufficiently proficient in javascript to see if you
can alleviate that problem in flapjax, but IMHO, that's really a
problem you have at the denotational level.

If you look at the encodings I propose either you need to represent
the state of affairs "no event occurred yet" or "there is no event
now" and the behaviors depending on these encoded events will have to
deal with that potential state so it must "leak" into the
representation.

Now there may be other ways to encode events as behaviors, but None
that I can think of right now.

Best,

Daniel

[1] http://erratique.ch/software/react

Reply all
Reply to author
Forward
0 new messages