<span class="gmail_quote">On 12/12/06, <b class="gmail_sendername">Brian Hulley</b> &lt;<a href="mailto:brianh@metamilk.com">brianh@metamilk.com</a>&gt; 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 &quot;reversal&quot;.&nbsp; Can you elaborate on what you mean by &quot;the imperative approach&nbsp;&nbsp;imposes an implementation dependence of inputs on outputs.&quot; In the model-view-controller pattern for example, I see no such reversal.
<br></blockquote><br>I'll try to explain with an example.&nbsp; 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.&nbsp; It then installs event handlers
for the input widget, to change the state of output widget (to show the square of the input value).&nbsp; 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;">
&nbsp; do&nbsp; -- Create frame, panel, slider input, and text output</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f&nbsp;&nbsp;&nbsp; &lt;- frame []</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pan&nbsp; &lt;- panel f&nbsp; []</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s&nbsp;&nbsp;&nbsp; &lt;- hslider pan True 0 10 [ selection := 3 ]
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t&nbsp;&nbsp;&nbsp; &lt;- textEntry pan []</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- 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;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let upd = do&nbsp; n &lt;- get s selection</span>
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set t [ text := show (n*n) ] </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; upd</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set s [ on command := upd ]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- Lay out panel and frame</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set pan&nbsp; [&nbsp; layout :=</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fill $ column 0 [ hwidget s, hwidget t ] ]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set f&nbsp;&nbsp;&nbsp; [ layout := hwidget pan ]</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp; hwidget :: Widget w =&gt; w -&gt; Layout</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp; 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.&nbsp; Thus, the implementation dependencies are opposite of the logical dependencies.&nbsp; 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,&nbsp; - Conal<br><br>