[Haskell-cafe] ANN: Netwire 1.2.4

Ertugrul Soeylemez es at ertes.de
Sun Sep 11 17:11:47 CEST 2011

Hello there,

version 1.2.4 of netwire is out.  Major changes:

  * Changed the semantics of time.  Previously if a wire was not run
    (because of an earlier inhibiting wire), then its local time was
    suspended.  Example:

        proc _ -> do
            t1 <- time -< ()
            fps1 <- avgFps 1000 -< ()

            require_ <<< wackelkontakt -< ()
            t2 <- time -< ()
            fps2 <- avgFps 1000 -< ()

            identity -<
                printf "Time: %8.2f %8.2f\nFPS : %8.2f %8.2f"
                       t1 t2 fps1 fps2

    In the previous version t2 would be about half of t1, because the
    {require_ <<< wackelkontakt} wire inhibits for about half of all
    instances.  Further fps1 and fps2 would be about equal.  In other
    words, time was local, while FPS were global.  This is not very
    useful in practical applications.

    With the new semantics t1 and t2 will be equal.  Instead the
    framerate will drop after the inhibiting wire, such that fps2 will
    be about half of fps1.  So now time is global and FPS are local.

    This is useful e.g. in a stateless network application (like a web
    app) to ban users, who are trying logins too fast.  The following
    wire allows one login trial per second in average over the last 10
    trials (the faster you try the longer you have to wait):

        login :: Wire MyApp IpAddress User
        login = context $ proc ipAddr -> do
            fps <- avgFps 10 -< ()
            require_ -< fps < 1
            {- login procedure -}

    Used with ArrowPlus this easily lets you fetch the currently logged
    in user from the session, and if there is none, request a login:

        getUser :: Wire MyApp IpAddress User
        getUser = getCurrentUser <+> login

  * Context-sensitive wires.  There is now a new wire transformer called
    'context', which is essentially a context switcher establishing
    multiple wire threads of control:

        context :: (Ord a, Monad m) => Wire m a b -> Wire m a b

    It takes a base wire and evolves it individually for each possible
    input value.  This is a very convenient alternative to parallel
    routing switches.

    The 'context' wire transformer never forgets a context.  For many
    applications (like sessions in a web application) this is not
    desirable.  For them there is an alternative transformer
    'contextLimited', which allows you to garbage-collect.

Minor changes:

  * More responsive calculus wires.  Reflect changes immediately without
    the one-instant delay.  If you need the delay for feedback, use
    'delay' explicitly.

  * New analysis wires 'collect' and 'lastSeen'.

  * New inhibition wires 'forbid_', 'inhibit_' and 'require_'.

  * Separate session starting/cleaning functions in FRP.NetWire.Session.
    However, the exception-safe withWire function is the preferred way.

  * Optimized internal representation.  There are now only two
    constructors WGen and WArr for the Wire type instead of four.  I
    dropped WConst and WId, because they are representable as special
    cases of WArr without noticable performance loss.  This improves
    overall performance, because now there are only two constructors to
    pattern-match against.

Right now I'm working intensively on netwire, so if you have any feature
requests, just mail me.  There is a good chance to find your desired
feature implemented quickly.

Note:  I have been too quick with version numbers.  Major version 2 will
be the one with the stabilized API, so for now with increasing minor
version numbers (but not patch levels!) you have to be prepared for API
changes, although I don't expect big changes anymore.

Enjoy and keep the feedback coming!


nightmare = unsafePerformIO (getWrongWife >>= sex)

More information about the Haskell-Cafe mailing list