Push vs pull, rather than imperative vs functional, as the crux of the inversion issue makes a lot of sense to me. And I see your point about publish/subscribe removing the dependency inversion, while keeping a push implementation and an imperative style. I also see how pull can be done easily in an imperative setting. As for doing push in a functional approach, do you mean under the hood, or somehow a visible push model? Phooey does push under the hood, but hides it from the user. I don't know what a functional, visible push model would look like.
If I understand your final paragraph below, you're describing what I'm up to with Phooey: specify connections (dependencies) in a simple, declarative way, and have the notifications all set up correctly. Thanks for your comments, Steve. They're getting me closer to a clear explanation, which will be helpful in the paper I'm writing. Regards, - Conal On 12/13/06, Steve Schafer <[EMAIL PROTECTED]> wrote:
On Tue, 12 Dec 2006 17:54:26 -0800, you wrote: >Notice that although, logically, the output depends on the input (being a >rendering of its square), the code places into the input widget a dependency >on the output widget, because the output widget contains the mutable state >altered by the input widget's event handler (upd). Moreover, the output >widget contains no reference to the input widget. Thus, the implementation >dependencies are opposite of the logical dependencies. This inversion of >dependencies would seem to be a direct result of the imperative approach, >which states the actions that must be taken on the output state as a >consequence of changes to the input state. I don't think it's the result of an imperative vs. functional approach. It's basically a matter of push vs. pull, and while the functional (especially lazy functional) approach is most naturally a pull technique, you can do both push and pull using either imperative or functional approaches. In fact, before the advent of event-driven programming (the ultimate push technique), most user interaction in imperative programming was based on pull techniques. (And it's somewhat ironic that event-driven programming is typically implemented via a polling loop or other such pull mechanism.) The bottom line is that you have to respond to sequenced, asynchronous events, which are awkward to model using purely pull techniques. You can alleviate some of the "invertedness" of the dependencies by using a publish/subscribe model, where the subscriber (the output widget in this example), subscribes to notifications by registering itself with the publisher (the input widget). It still ends up working more or less the same way under the hood, but at least the only _explicit_ linkage visible in the source code goes from output widget -> input widget rather than the other way around. I haven't studied Fran or the other functional user interaction implementations in any detail, so it's possible that I'm repeating something here that they already do, but I think the most useful thing that could come out of any work in this area would be a notation that allows the programmer to set up the notification links in some sort of declarative way (i.e., "This is how all of the widgets are supposed to be hooked up together"). There are still some sticky bits, because there's always the possibility that the order in which the connections are wired up will have an effect on whether the final contraption works as expected, but it should be possible to avoid problems in that regard with the addition of some dependency notations. Steve Schafer Fenestra Technologies Corp. http://www.fenestra.com/ _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
_______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell