[reactive] event merge problem?

Conal Elliott conal at conal.net
Tue Dec 16 19:12:17 EST 2008


There's definitely a sneaky bug hiding somewhere.  I'm still looking for a
simple test case, preferably independent of the imperative/legacy adapter
code.  - Conal

On Tue, Dec 16, 2008 at 3:04 PM, Peter Verswyvelen <bugfact at gmail.com>wrote:

> Ah yes, you are right.  So, if I understood it correctly, it is the
> intention to use the partially evaluated data constructors to be able to
> pattern match against e.g. NoBound a, even when a is not computed yet. So
> yes, if an event has NoBound occurrences, and this event immediately
> provides NoBound for the next future value even when the exact time is not
> yet known, then I indeed don't see why the pattern match against MaxBound
> would block... Mmm, Bob?
>
> On Tue, Dec 16, 2008 at 11:51 PM, Conal Elliott <conal at conal.net> wrote:
>
>> Time in Reactive has some structure.
>>
>>     type Time t = Max (AddBounds t)
>>
>> Max adds a max-based Monoid instance.  It's a newtype and so doesn't add
>> any laziness/partiality.  AddBounds, however, is a data type:
>>
>>     data AddBounds a = MinBound | NoBound a | MaxBound
>>
>> Typically, the type parameter t in 'Time t' is bound to 'Improving
>> Double', which adds yet more partiality to times.
>>
>> External inputs are represented by events whose occurrence times are
>> wrapped with NoBound.  The various matches against MaxBound then ought to
>> fail immediately, without any examination of the improving double inside the
>> NoBound.
>>
>> That's my intention, anyway.  There may be a bug somewhere that thwarts
>> this trick.
>>
>> I don't yet have a concrete example of the merge bug that Bob mentioned.
>> Once I have one, I'll see what I can learn about it.
>>
>>   - Conal
>>
>>
>>
>> On Tue, Dec 16, 2008 at 1:00 PM, Peter Verswyvelen <bugfact at gmail.com>wrote:
>>
>>> But isn't just matching against MaxBound or MinBound enough to enforce
>>> the computation of the time value? And hence block when the event is
>>> not-never-occuring (hu that sounded weird)?
>>> 2008/12/16 Conal Elliott <conal at conal.net>
>>>
>>>> Yes indeed.  The issue is that if you know one of the events will never
>>>>> happen again, what you want to do is stop merging, and throw the
>>>>> never-occurring event in the bin.  Unfortunately, to pattern match against
>>>>> the never occurring event then blocks checking whether the match works or
>>>>> not :(.
>>>>
>>>>
>>>> I'm trying to understand what the problem is here.  I think the
>>>> not-yet-known values are all wrapped with a NoBound and so should pass right
>>>> by the MaxBound pattern matches without blocking.
>>>>
>>>>   - Conal
>>>>
>>>> On Tue, Dec 16, 2008 at 2:56 AM, Thomas Davie <tom.davie at gmail.com>wrote:
>>>>
>>>>>
>>>>> On 16 Dec 2008, at 11:50, Claus Reinke wrote:
>>>>>
>>>>>  Seems to be partially timer- and partially event-merge-related:
>>>>>>>> if I compile with -threaded, the pieces do not move at all on their
>>>>>>>> own, but as long as I keep pressing "down", the game appears
>>>>>>>> playable as intended; if I compile without -threaded, the pieces
>>>>>>>> move occasionally, but the effects of keyboard input are entirely
>>>>>>>> unpredictable.
>>>>>>>>
>>>>>>>
>>>>>>> I've noticed this behavior in since the last couple of days, So at a
>>>>>>>  guess a bug got introduced
>>>>>>> somewhere along the line.  The merge issue  is known -- at the
>>>>>>> moment, an occurrence doesn't
>>>>>>> appear in the output  until it's known whether or not the other event
>>>>>>> ever occurs, which  isn't
>>>>>>> ideal.  Unfortunately, the obvious fix for the issue creates a  large
>>>>>>> memory leak, I've been
>>>>>>> playing with a few ways to fix this.
>>>>>>>
>>>>>>
>>>>>> Thanks for the info, Tom,
>>>>>>
>>>>>> where can I find more details about this merge issue? Given that
>>>>>> FRPLs are traditionally synchronously concurrent languages, this
>>>>>> is rather surprising: when sampling anything, one knows about
>>>>>> everything's values _now_, which should be sufficient for merge,
>>>>>> no matter whether the other event might or might not happen later.
>>>>>>
>>>>>
>>>>> Yes indeed.  The issue is that if you know one of the events will never
>>>>> happen again, what you want to do is stop merging, and throw the
>>>>> never-occurring event in the bin.  Unfortunately, to pattern match against
>>>>> the never occurring event then blocks checking whether the match works or
>>>>> not :(.  The particular interesting bit of code is in PrimReactive.hs
>>>>> (Conal's comments here):
>>>>>
>>>>> -- | Merge two 'Future' streams into one.
>>>>> merge :: Ord t => Binop (FutureG t (ReactiveG t a))
>>>>>
>>>>> -- The following two lines seem to be too strict and are causing
>>>>> -- reactive to lock up.  I.e. the time argument of one of these
>>>>> -- must have been _|_, so when we pattern match against it, we-- block.
>>>>> --
>>>>> -- On the other hand, they patch a massive space leak in filterE.
>>>>>  Perhaps
>>>>> -- there's an unamb solution.
>>>>>
>>>>> Future (Max MaxBound,_) `merge` v = v
>>>>> u `merge` Future (Max MaxBound,_) = u
>>>>>
>>>>> u `merge` v =
>>>>>  (inFutR (`merge` v) <$> u) `mappend` (inFutR (u `merge`) <$> v)
>>>>>
>>>>> -- What's going on in this 'merge' definition?  Try two different
>>>>> -- future paths.  If u arrives before v (or simultaneously), then
>>>>> -- begin as u begins and then merge v with the rest of u.  Otherwise,
>>>>> -- begin as v begins and then merge u with the rest of v.  Because of
>>>>> -- the left-bias, make sure u fragments are always the first argument
>>>>> -- to merge and v fragments are always the second.
>>>>>
>>>>>
>>>>> Bob
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> Reactive mailing list
>>>> Reactive at haskell.org
>>>> http://www.haskell.org/mailman/listinfo/reactive
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/reactive/attachments/20081216/c0008181/attachment-0001.htm


More information about the Reactive mailing list