<blockquote style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">... World -&gt; (x, World) ...<br></blockquote><blockquote style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">

<div> </div></blockquote><blockquote style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">I look at this World parameter as purely hypothetical, a trick used to 
gain an intuition. Whereas Jerzy (I think) uses it to claim Haskell is 
referentially transparent - those differing x and y values come from 
different worlds, or different world-states.<br></blockquote><div><br>I don&#39;t see this interpretation in Jerzy&#39;s words, and I&#39;d be very surprised if he had that sort of argument in mind.<br><br><blockquote style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">

If main returns a function of type &quot;World -&gt; (x, World)&quot; wrapped in ...<br></blockquote><div><br>Main does not return or denote such a thing. The idea that Haskell IO can be accurately explained as (i.e., denotes) World -&gt; (x,World) is a persistent myth. That model cannot explain concurrency (even with the outside world) or nondeterminism, both of which are part of Haskell IO. We don&#39;t have an precise &amp; accurate denotational model for IO, in contrast to most other types in Haskell. Which is to say that while much of Haskell programming is denotative, IO programming is not. Peter Landin, an important figure in functional programming, proposed and defined this term &quot;denotative&quot; as a substantive &amp; precise replacement for the fuzzier notions of &quot;functional&quot; and &quot;declarative&quot;. He offered his definition and suggested that &quot;When faced with a new notation that borrows the functional appearance of everyday algebra, it is (c) that gives us a test for whether the notation is genuinely functional or merely masquerading.&quot;<br>

<br>Of course, various subsets of IO can be precisely and accurately modeled, but so far not IO as we use it. It&#39;s very unlikely that we ever will have such a (precise &amp; accurate) model, and by design, as explained at <a href="http://conal.net/blog/posts/notions-of-purity-in-haskell/#comment-22829">http://conal.net/blog/posts/notions-of-purity-in-haskell/#comment-22829</a> .<br>

<br>  - Conal<br></div></div><br><div class="gmail_quote">On Sun, Jan 1, 2012 at 7:43 PM, Steve Horne <span dir="ltr">&lt;<a href="mailto:sh006d3592@blueyonder.co.uk">sh006d3592@blueyonder.co.uk</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On 01/01/2012 22:57, Jerzy Karczmarczuk wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Dan Doel :<br>
...<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Also, the embedded IO language does not have this property.<br>
<br>
     do x&lt;- m ; f x x<br>
<br>
is different from<br>
<br>
     do x&lt;- m ; y&lt;- m ; f x y<br>
<br>
and so on. This is why you shouldn&#39;t write your whole program with IO<br>
functions; it lacks nice properties for working with your code.<br>
</blockquote>
Sorry, what are you trying to suggest?<br>
<br>
You show two OBVIOUSLY different pieces of code, and you say that they<br>
are different.<br>
If, by chance, some newbie reads that and gets the impression that<br>
(&lt;-) is something equivalent to (=), you are serving the devil.<br>
<br>
</blockquote></div>
Speaking as the devil...<br>
<br>
The do-notation sugar may confuse the issue - the &lt;- looks like an operator, but translating to binds-and-lambdas form suggests otherwise. Quick translations (I hope no mistakes) with lots of parens...<br>
<br>
  m &gt;&gt;= (\x -&gt; (f x x))<br>
<br>
  m &gt;&gt;= (\x -&gt; (m &gt;&gt;= (\y -&gt; (f x y))))<br>
<br>
At first sight, these two expressions can give different results for reasons other than evaluation order. In particular, there are two bind operators, not just one.<br>
<br>
That is, x and y could get different values for reasons other than the two m references referring to different things. So... is that true?<br>
<br>
Of course even the bind operator arguably isn&#39;t primitive. We could translate to get rid of those too, and see what lies underneath. This is where we start seeing functions of type...<br>
<br>
  World -&gt; (x, World)<br>
<br>
Problem - this level of abstraction is hypothetical. It is not part of the Haskell language. Haskell specifically defines the IO monad to be a black box.<br>
<br>
I look at this World parameter as purely hypothetical, a trick used to gain an intuition. Whereas Jerzy (I think) uses it to claim Haskell is referentially transparent - those differing x and y values come from different worlds, or different world-states. I&#39;m not entirely sure, though, as we got sidetracked.<br>


<br>
If main returns a function of type &quot;World -&gt; (x, World)&quot; wrapped in a monad context, then there is referential transparency as defined in computer science. But is that a fair claim?<br>
<br>
In this model, Haskell is an interpreted language for compositing functions. We can call those functions programs. The executable is a translation of the function returned by main, but *not* a translation of the source code.<br>


<br>
But GHC is called a compiler, and compilation is usually considered a kind of translation - the executable is a translation of the source code. GHCi is an interpreter, but it doesn&#39;t stop at returning a function of type World -&gt; (x, World) - it does the I/O. And the reason we use these terms is because, as programmers, we think of the executable as the program - as a translation of the source code.<br>


<br>
So what main returns - that hypothetical function World -&gt; (x, World) - isn&#39;t just a product of the program, it&#39;s also a representation of the program.<br>
<br>
I&#39;ve made similar points before, but how do they work out this time...<br>
<br>
So...<br>
<br>
  when           evaluate what             effects  referentially transparent<br>
  -------------  ------------------------  ------- -------------------------<br>
  compile-time   main                      no       yes<br>
  run-time       main someParticularWorld  yes      yes(?)<br>
<br>
I&#39;ve proved effects at run-time, but in this model, the intermediate and final world-states are products of the evaluation of that &quot;main someParticularWorld&quot; expression. Even the results extracted from input actions are referentially transparent - or if not, we&#39;re dealing with the philosophy of determinism.<br>


<br>
It&#39;s probable that Jerzy told me this earlier and I wasn&#39;t ready to hear it then.<br>
<br>
However - we can say basically the same things about C. The World parameter is implicit in C but then it&#39;s implicit in Haskell too. Everything inside the IO monad black box is outside the scope of the Haskell language except in that semantics are defined for the primitive IO actions - basically what happens when a result is extracted out as part of evaluating a bind. That &quot;(?)&quot; in the &quot;yes(?)&quot; is because this is all contingent on that hypothetical World -&gt; (x, World) function hidden inside the IO monad context, which is not specified in the Haskell language.<br>


<br>
When I say that Haskell lacks referential transparency because the execution of primitive IO actions is tied to the evaluation of the bind operators that extract out their results, and different executions of the same action yield different results, I&#39;m only appealing to the defined semantics of the Haskell language. I&#39;m not appealing to a hypothetical model where the world is passed as a parameter.<br>


<br>
OTOH, this World -&gt; (x, World) model is much more appealing than my partially-evaluated-functions-<u></u>as-AST-nodes model.<br>
<br>
So - the issue seems to be whether the IO monad is a context holding world-manipulating functions, or whether it&#39;s a black box with semantics specified at the bind level. And if referential transparency is decided at this level, what practical relevance does it have?<br>


<br>
It&#39;s probably better to stick with &quot;the functional core is referentially transparent - IO actions break that, so don&#39;t overuse the IO monad&quot;. You can argue &quot;may or may not break that depending on your viewpoint&quot;, but if you can&#39;t objectively decide which viewpoint is correct, then you haven&#39;t proven referential transparency.<div class="HOEnZb">

<div class="h5"><br>
<br>
<br>
______________________________<u></u>_________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br>