Hi Neil,
On 9 Nov 2009, at 14:50, Neil Brown wrote:
1. Does anyone have any comments, on either version?
There is no way to remove an observer, which is something I'd expect
to have available. I realise this would require assigning a key to
each observer (and thus perhaps storing them in an associative map)
or some way to filter them, but I think if you can only ever add
observers, it will get awkward.
Good point. This occurred to me when I referred to the Gang of Four
book, while changing names for consistency. I must confess, in my
current project I haven't needed it, but I see your point.
2. In particular, is the MVar version sensible? I'm aiming for
mutual exclusion between threads. I _think_ I've got it, but I'm
perhaps not familiar enough with the semantics of MVar to be
certain. Advice appreciated. If it _is_ sensible, then is there
any reason not to just use this, and discard the IORef version?
It looks fine (and thread-safe) to me, but I'd agree that you may as
well just use the MVar version and leave out the IORef version.
Cool, thanks.
was a bit surprised at first that the observers were called
synchronously. Asynchronous is what I'd expect, and it's also
harder to code the asynchronous handlers wrongly. One blocking
call (such as putMVar) in a synchronous handler can screw up your
whole program by delaying the subsequent observers (and at that
stage, the order in which the observers were added begins to matter).
True, but the observers shouldn't be able to access the MVars
directly, I think? They should only be able to use the exposed
interface, which won't let that happen?
But my idea of how asynchronous would be implemented seems different
to yours, judging by your description. Why not just augment this
function in the synchronous version:
notifyObservers :: Subject sub val => sub -> IO ()
notifyObservers subject =
do value <- getValue subject
observers <- getObservers subject
mapM_ ($ value) observers to become:
notifyObserversAsync :: Subject sub val => sub -> IO ()
notifyObserversAsync subject =
do value <- getValue subject
observers <- getObservers subject
mapM_ (forkIO . ($ value)) observers
This is what I was expecting to happen -- all the observer actions
are spawned off into their own thread to run whatever code they want
(either communicating back to an existing thread, or performing some
long in-depth action).
Interesting. That might be quite sensible. My thoughts have probably
been coloured by how I've been doing things in wx. Ta for the
suggestion.
Cheers,
-Andy
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe