[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: mirage + froc = self-scaling?



On Thu, May 2, 2013 at 9:38 AM, Daniel BÃnzli
<daniel.buenzli@xxxxxxxxxxxx> wrote:
> Le mercredi, 1 mai 2013 Ã 21:07, Anil Madhavapeddy a Ãcrit :
>> [..]
> [..]
> The problem is that React has the premise that there can be no two 
> *primitive* signals/events (inputs to the system) that happen at the same 
> instantaneous time. Each change to a primitive triggers an update cycle that 
> you have to consider atomically. In animation you are usually not interested 
> in updating that image signal beyond 60Hz, so if you change say three colors 
> of a picture between two frames you don't actually want to recompute trice 
> the picture.
>
> Now you can circumvent this problem within react itself:
>
> let on_frame, redraw = E.create ()
> let resample prim = E.hold (S.value prim) (E.sample on_frame prim)
>
> but it feels artificial, you'd have to `resample` all your primitives before 
> using them to define your image, and could become inefficient if you have 
> many primitives.
>
> The good news is that this limitation is purely artificial and react can 
> perfectly be adapted to support simultaneous primitive updates, I just need 
> to devise an api that exposes an abstract type to some parts of react's 
> internal mechanism. But again I need to think more about this and write code.

The way froc handles this is not completely satisfactory. It doesn't
behave well in concurrent programs.

In froc, one can register new values for as many primitives as one
wants and then call a `sync` function. I don't remember the exact
names for the functions but basically it looks like:

~~~~~~~
create: unit -> (('a -> unit) * 'a t) (* the returned closure does not
trigger an update cycle *)
sync: unit -> unit (* triggers an update cycle *)
~~~~~~~

Good thing one can do:
- erase stall values before they were propagated in the dependency graph,
- change several values at the same time

Bad things that can happen:
- another thread might erase values you registered,
- another thread might start an update cycle before you registered all
the values you wanted


What I'd like it to look like:

~~~~~~~
create: unit -> ('a pusher * 'a t)
write: (\exist 'a . ('a * 'a pusher)) list -> unit (* push several
values on several primitive signals instantaneously *)
~~~~~~~

Good thing one can do:
- erase stall values before pushing (i.e. prepare the push-list by
both appending and removing/replacing entries),
- change several values at the same time

Bad thing one can do:
- get confused with existential types

(Although existential types are not really needed.

~~~~~~~
create: unit -> ('a pusher * 'a t)
type poly_pusher
val poly: 'a pusher -> 'a -> poly_pusher
val sync: poly_pusher list -> unit
~~~~~~~

)


Ciao,
-- 
______________
RaphaÃl Proust



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.