On Sun, Feb 8, 2009 at 6:25 PM, Richard O&#39;Keefe <span dir="ltr">&lt;<a href="mailto:ok@cs.otago.ac.nz">ok@cs.otago.ac.nz</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="Ih2E3d"><br>
On 6 Feb 2009, at 4:20 am, Gregg Reynolds wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
&nbsp;However, consider:<br>
<br>
 &nbsp; &nbsp;getChar &gt;&gt;= \x -&gt; getChar<br>
<br>
An optimizer can see that the result of the first getChar is discarded and replace the entire expression with one getChar without changing the formal semantics.<br>
</blockquote>
<br></div>
But the result of the first getChar is *NOT* discarded.<br>
**As an analogy**, think of the type IO t as (World -&gt; (t,World))<br>
for some hidden type World, and<br>
 &nbsp; &nbsp; &nbsp; &nbsp;getChar w = (c, w&#39;)<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-- get a character c out of world w somehow,<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-- changing w to w&#39; as you go<br>
 &nbsp; &nbsp; &nbsp; &nbsp;(f &gt;&gt;= g) w = let (v,w&#39;) = f w in (g v) w&#39;<br>
<br>
In this analogy, you see that the result of getChar is a value of<br>
type IO Char (not of type Char), and that while the character<br>
part of the result of performing the result of getChar may be<br>
discarded, the &quot;changed world&quot; part is NOT.</blockquote><div><br>That&#39;s an implementation detail.&nbsp; It doesn&#39;t account for other possible IO implementations. <br></div></div><br>My original question was motivated by the observation that a human reader of an expression of the form &quot;e &gt;&gt;= f&quot; , on seeing that f is constant, may pull the constant value out of f, disregard e and dispense with the application f e.&nbsp; So can a compiler, unless IO expressions are involved, in which case such optimizations are forbidden.&nbsp; I wondered if that was due to the semantics of &gt;&gt;= or the semantics of IO.<br>
<br>To summarize what I&#39;ve concluded thanks to the helpful people on haskell-cafe:<br><br>The compiler can optimize e &gt;&gt;= f except for any IO expressions in e and f.&nbsp; IO expressions must be evaluated, due to the semantics of IO.&nbsp; The may not be disregarded, memoized, or substituted.&nbsp; IO semantics may be implemented in different ways by different compilers; these implementation techniques are not part of the formal semantics of the language, which may be expressed as above:&nbsp; IO expressions must be evaluated wherever and whenever they occur.&nbsp; <br>
<br>The bind operator &gt;&gt;= enforces sequencing on arguments containing IO expressions, but does not force evaluation.&nbsp; Even bind expressions involving IO may be optimized.&nbsp; For example:<br><br>&nbsp; getChar &gt;&gt;= \x -&gt; ...&lt;monster computation&gt;... putChar &#39;c&#39;<br>
<br>The compiler may discard &lt;monster computation&gt; (assuming it contains no IO expressions), but it must evaluate getChar and putChar (due to IO semantics) in the correct order (due to bind semantics).<br><br>Thanks all,<br>
<br>gregg<br>