
[this has drifted off-topic quite a bit, so new subject] On Sunday 28 November 2004 17:29, Benjamin Franksen wrote:
I think it would get quite awkward as soon as you want to provide
- more mutable members - synchronized access + asynchronous methods
(i.e. _reactive_ objects)
I am ready to be proved wrong, though.
The view of indefinite blocking as a transparent operational property dates back to the era of batch-oriented computing, when interactivity was a term yet unheard of, and buffering operating systems had just become widely employed to relieve the programmer from the intricacies of synchronization with card-readers and line-printers. Procedure-oriented languages have followed this course ever since, by maintaining the abstraction that a
I couldn't wait so I proved myself wrong myself ;) Since I didn't get the extensible records example to compile, I translated it to normal Haskell records. The state is still only one mutable Int but the object is fully reactive. The code is attached and I do not find it awkward (although the generic object API could still be improved). One problem remains: to preserve reactivity, the programmer must make sure that methods don't execute IO actions that may block indefinitely. Unfortunately there is no way in Haskell to enforce this, because (indefinitely) blocking IO actions have the same type as non-blocking ones. Too late to change that, I guess... Btw, here is one of my all-time favourite quotes: program environment is essentially just a subroutine that can be expected to return a result whenever the program so demands. Selective method filtering is the object-oriented continuation of this tradition, now interpreted as ``programmers are more interested in hiding the intricacies of method-call synchronization, than preserving the intuitive responsiveness of the object model''. Some tasks, like the standard bounded buffer, are arguably easier to implement using selective disabling and queuing of method invocations. But this help is deceptive. For many clients that are themselves servers, the risk of becoming blocked on a request may be just as bad as being forced into using polling for synchronization, especially in a distributed setting that must take partial failures into account. Moreover, what to the naive object implementor might look like a protocol for imposing an order on method invocations, is really a mechanism for reordering the invocation-sequences that have actually occurred. In other words, servers for complicated interaction protocols become disproportionately easy to write using selective filtering, at the price of making the clients extremely sensitive to temporal restrictions that may be hard to express, and virtually impossible to enforce. <<< (see http://www.cs.chalmers.se/~nordland/ohaskell/rationale.html) Cheers, Ben