<span class="gmail_quote">On 12/12/06, <b class="gmail_sendername">Brian Hulley</b> <<a href="mailto:brianh@metamilk.com">brianh@metamilk.com</a>> wrote:<br></span><blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote">
This looks really interesting, but I'm struggling to understand what you mean by "reversal". Can you elaborate on what you mean by "the imperative approach imposes an implementation dependence of inputs on outputs." In the model-view-controller pattern for example, I see no such reversal.
<br></blockquote><br>I'll try to explain with an example. If it's not clear, or you think the reasoning doesn't apply to MVC, please let me know.<br><br>
The code makes a top-level frame and a panel for holding widgets,
creates slider input and text output. It then installs event handlers
for the input widget, to change the state of output widget (to show the square of the input value). After
initializing the output, the code set the panel's and the frame's
layouts and shows the frame.<br>
<br><div style="margin-left: 40px;"><span style="font-family: courier new,monospace;">import Graphics.UI.WX</span><br style="font-family: courier new,monospace;"></div><br><div style="margin-left: 40px;"><span style="font-family: courier new,monospace;">
z1 :: IO ()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">z1 = start $</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
do -- Create frame, panel, slider input, and text output</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> f <- frame []</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> pan <- panel f []</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> s <- hslider pan True 0 10 [ selection := 3 ]
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> t <- textEntry pan []</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
-- output-updater to be called initially and when input changes</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> let upd = do n <- get s selection</span>
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> set t [ text := show (n*n) ] </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
upd</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> set s [ on command := upd ]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
-- Lay out panel and frame</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> set pan [ layout :=</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
fill $ column 0 [ hwidget s, hwidget t ] ]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> set f [ layout := hwidget pan ]</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> hwidget :: Widget w => w -> Layout</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> hwidget = hfill . widget</span><br></div><br>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 (
<span style="font-family: courier new,monospace;">upd</span>). 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.
<br><br>I'll reply separately to your question about efficient evaluation/updating.<br><br>Cheers, - Conal<br><br>