First of all, I apologize about my first message. Now I understand React can be
easily adapted to send a value during update cycle by using thunk. To forbid
sending events during update cycle in React is not restriction but design 
choice.

(2012/04/18 22:27), Daniel Bünzli wrote:
> and now what should the value of e be in the next update cycle ? All the options you have (keep only the first call to sender, keep only the last call to sender, keep both and execute one after the other) break the functional and compositional nature of FRP because it violates the semantics of events.

PEC takes the third option. I understand that the evaluation order of update
are problematic.

module E = Pec.Event.Make (Pec.EventQueue.DefaultQueueM) 
(Pec.EventQueue.DefaultQueueI)
open Printf

let _ =
  let e, sender = E.make () in
  let e' = E.map (fun x -> sender 2; x + 1) e in
  let e'' = E.map (fun x -> sender 3; x + 1) e in
  let _ = E.subscribe (printf "e=%d\n") e in
  let _ = E.subscribe (printf "e'=%d\n") e' in
  let _ = E.subscribe (printf "e''=%d\n") e'' in
  sender 1;
  ignore (E.run ());
  printf "---\n";
  ignore (E.run ());
  printf "---\n";
  ignore (E.run ());
  printf "end\n"

This program outputs:

e=1
e'=2
e''=2
---
e=2
e'=3
e''=3
---
e=3
e'=4
e''=4
end

This result rely on order of applying subscribe function. I think any program
depending on the evaluation order of updates are not good one.

But I'm not sure why only sending a value to event breaks functional and compos-
itional nature of FRP. I think all side-effects during update cycle are breaks
functional and compositional nature of FRP too, because the results of both 
programs
are depends on evaluation order of updates.

A:
let e' = E.map (fun x -> sender 1; x + 1) e in
let e'' = E.map (fun x -> sender 2; x + 1) e in

B:
let e' = E.map (fun x -> print_int 1; x + 1) e in
let e'' = E.map (fun x -> print_int 2; x + 1) e in

Are there any special problem in program A? In other word, program B keeps
functional and compositional nature of FRP?

Yes, weak-pointer-less implementation is one of my purpose. The key point is
that dependency of events are represented by nested variants.

That doesn't really answer my question (or at least I don't understand what it 
means).

Inside PEC, "let e' = E.map f e" is just variant instance.

  let map f e = Wrap {
    event = e;
    wrap = f;
    w_latest = None;
  }

Another primitive combinator functions also just makes a variant instance.

  and 'a event =
    | Cell : 'a mcell -> 'a event
    | Wrap : ('a, 'b) mwrap -> 'b event
    | Choose : 'a choose -> 'a event
    | Never : 'a event
    | Switch : 'a mswitch -> 'a event

So an event value itself is a nested variant instance which can be GCed freely
when user-level references are disappear. (There are no library level 
reference.)

When an event is subscribed, the argument function are set in source events of
subscribed event. This means subscribed events are never GCed until source 
events
are GCed.(or until unsubscribe.)

If one of source events are fired, dependent events marked with subscribe 
functions
are updated. Weak pointer does not needs in that algorithm.


Best Regards,
 Ogasawara

--
Caml-list mailing list.  Subscription management and archives:
https://sympa-roc.inria.fr/wws/info/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

Reply via email to