<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On 5 Feb 2008, at 10:14 PM, Jeff φ wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><br><br> <div class="gmail_quote">On Feb 5, 2008 4:58 PM, Chaddaï Fouché &lt;<a href="mailto:chaddai.fouche@gmail.com">chaddai.fouche@gmail.com</a>&gt; wrote:<br> <blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">2008/2/5, Jeff φ &lt;<a href="mailto:jeff1.61803@gmail.com">jeff1.61803@gmail.com</a>&gt;:<br> <div class="Ih2E3d">&gt; This is interesting.  I've been programming in Concurrent Clean for a while.<br>&gt;  Instead of monads, Clean supports unique types for mutable arrays and IO.<br>&gt; In Clean, I can write code that iterates through a mutable array by<br> &gt; converting it to a lazy list.  This is convenient because I can use all the<br>&gt; nice list processing functions that are available.<br>&gt;<br><br></div>You could absolutely write something like that in Haskell, but as some<br> have pointed out, this is probably _not a Good Idea_, even though it<br>works in your particular case, the array could be modified between the<br>time you get the lazy list and the time you actually read it... And<br>there's no way to insure it's not happening in Haskell, and I strongly<br> doubt there is in Concurrent Clean, could you confirm ?<br></blockquote> <div> <div>Concurrent Clean can handle this in a safe way.  Here's a code snippet for normalize_2D_ary from ArrayTest.icl:</div></div></div> <div class="gmail_quote"> </div> <div class="gmail_quote"><font face="courier new,monospace">uToList_2D :: *(a u:(b c)) -&gt; (.[c],*(a u:(b c))) | Array a (b c) &amp; Array b c<br>map_in_place_2d_arr :: (a -&gt; a) *(b *(c a)) -&gt; *(b *(c a)) | Array b (c a) &amp; Array c a<br> </font></div> <div class="gmail_quote"><font face="courier new,monospace">normalize_2D_ary :: *(a *(b c)) -&gt; *(a *(b c)) | Array a (b c) &amp; Array b c &amp; / c &amp; Ord c<br></font><font face="courier new,monospace">normalize_2D_ary ary =<br>     let (lst,ary2) = uToList_2D ary<br>        max_elem = foldl1 max lst<br>    in  map_in_place_2d_arr (\ x -&gt; x / max_elem) ary2<br></font></div> <div class="gmail_quote">uToList_2D takes a unique array, ary, and returns a tuple containing a list of the array elements and a "new" array, ary2.  uToList_2D does not modify ary, but Clean's type system forces any function that accesses a unique array to thread the array through and return a "new" array.  Under the hood the "new" array actually uses the same memory storage as the original array.  So, it is effecient.  Threading the array serializes access insuring the array won't be modified until the list is complete. </div></blockquote><div><br class="webkit-block-placeholder"></div><div>I'm confused --- does uToList_2D return the head of the list before or after it finishes reading the array?  If before, then I don't see how the type system prevents me from modifying the array before I finish examining the list, as you claim.  If after, then the list isn't truly lazy.</div><br><blockquote type="cite"><div class="gmail_quote"> The type system will generate an error if I wrote code that breaks referential transparency.</div> <div class="gmail_quote"> </div> <div class="gmail_quote">Array and IO Monads can be implemented in Clean on top of the uniqueness type system.  The do-notation could be added to the language.</div> <div class="gmail_quote">However, the comments I've read so far lead me to believe the code I've shown cannot be implemented in Haskell using a lazy list without resorting to unsafe functions.  I'm beginning to suspect the uniqueness type system of Clean is more general and flexible than Haskell's monads. </div></blockquote><div><br class="webkit-block-placeholder"></div>You mean this particular monad, of course.<br><div><br class="webkit-block-placeholder"></div>jcc</div><div><br></div></body></html>