|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [MirageOS-devel] Blog post on Irmin/CueKeeper
Le lundi, 22 juin 2015 Ã 20:58, Daniel BÃnzli a Ãcrit :
> Even if weak references are no longer used you will still get into problems
> with side effectful events/signals as you will never have any control on the
> order their update since by the very semantics of React all of these effects
> are supposed to happen simultaneously (synchrony hypothesis) but won't in
> practice.
>
With respect to this I somehow claim that while side effectful events/signals
may exist they should be hidden by interfacing libraries (int the very same
that they should hide the update step machinery).
If we take the example of your post you are basically trying to write to stdout
by creating many effectful events. This is not a very good idea (unfortunately
one that is actually shown in React's documentation itself) since in practice
many of these effectful events can happen during the same semantically
instantaneous instant and hence leaves the precise semantics of the final
effect wanting.
So the question we should ask ourselves is how can events or signals represent
this action in the FRP system so that it respects the FRP semantics and is
meaningful to our problem domain.
We can represent the channel by a string signal that stands for the complete
output so far. But this defeats the streaming aspect of channels as it keeps in
memory all that was output during the program. Events seem a better fit in this
case. stdout can be represented by a string event, each occurence of a string
on the event is meant to be output to the channel. Semantically the
time-ordered concatenation of all occurences of this event represent all that
was written to stdout.
Now of course this event will be provided by the program. So this leads to the
following interface:
module Stdout : sig
val set : string event -> unit
(** [set e] sets the sequence of strings to be output
to {!stdout} to the occurences of [e] *)
end = struct
let stdout = ref E.never
let set e = E.stop ~strong:true !stdout; stdout := E.map print_string e
end
It now is the task of your main function to produce this event, set it *once*
to interface with stdout and forget.
let main () =
let stdout = ... in
Stdout.set stdout;
run_loop ()
This reveals the beauty of FRP which is that by applying the denotational
semantics on the expression that defines the stdout event we can precisely
understand what may happen on stdout at a given point t in the lifetime of the
program.
But it also reveals its difficulty: everything that may happen on stdout needs
to be specified (linked) at a unique point in the program (but possibly through
a E.switched higher-order signal which allows for dynamics). However nobody is
allowed to discreetly poop on stdout without going through the event â if we
assume other printing function are banished. This means that every dependency
becomes explicit which could become painful to deal with (and difficult w.r.t.
to recursive data flow dependencies).
Note that by defining a single interaction point for the effect to happen we
solved the problem of old effectful signals not yet gc'd still trying to output
on stdout. And since a single event occurence defines what happens on stdout at
a given point in time, we also force the programmer to give a precise and
meaningful semantics if more than one entity wants to write on stdout
simultaneously; e.g. it could E.select a single event, or E.merge a list of
them, etc. but the final effect will be precisely defined w.r.t. the FRP
semantics.
One should really try not to reproduce the bad effectful signal examples in
React's doc and think in terms of denotations rather than update step,
callbacks and effectful signals and events.
Best,
Daniel
P.S. The Useri rendering surface interface has one or two of these "output
controllers" :
http://erratique.ch/software/useri/doc/Useri.Surface.html#VALset_mode_setter
http://erratique.ch/software/useri/doc/Useri.Surface.html#VALset_refresher
_______________________________________________
MirageOS-devel mailing list
MirageOS-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/mirageos-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |