<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:times new roman, new york, times, serif;font-size:12pt"><div>Hi Attila,<br><br>It's been a while for me too... I tried your code and the problem is<br><br>&nbsp;&gt;&gt;&gt; a.[n] &gt; 0 = (a.[n], a)<br><br>There are two uses of 'a' on the RHS. Fortunately, Clean comes with a![n], which does precisely what you want, returns a tuple with the value and the array for future use. So, if I understood what you wanted, the code ended like (omitting your other fib's, and I put Fib3_ top level ...)<br><br>---<br>module fib<br><br>import StdEnv<br><br>Fib3 :: Int -&gt; Int<br>Fib3 n<br>| n &lt; 0 = abort "Fib3: Called with negative parameter"<br>| otherwise = res<br>&nbsp;&nbsp;&nbsp; where<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (res, _) = Fib3_ n (createArray (n+1) 0)<br><br>Fib3_ :: Int *{Int} -&gt; (Int, *{Int})<br>Fib3_ n
 a<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | size a &lt; n&nbsp;&nbsp;&nbsp; = abort "cannot store fib(n) in a"<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | a.[n] &gt; 0&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = a![n]<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | n == 0&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = {a &amp; [0] = 1}![0]<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | n == 1&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = {a &amp; [1] = 1}![0]<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | otherwise<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # (res1, a) = Fib3_ (n-1) a<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # (res2, a) = Fib3_ (n-2) a<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = {a &amp; [n] = res1 + res2}![n]<br><br><br>Start :: Int<br>Start = Fib3 7<br>---<br><br>Note also the use of # to reuse the 'a' variable. So, it is unique in the 'otherwise' branch as well.<br><br>This can be generalized to memorize any Int -&gt; Int function, later...<br><br>Hope this
 helps<br><br>Carlos Aya<br></div><div style="font-family: times new roman,new york,times,serif; font-size: 12pt;"><br><div style="font-family: arial,helvetica,sans-serif; font-size: 13px;">-------------------------------<br>Message: 1<br>Date: Fri, 17 Oct 2008 15:02:25 -0400 (EDT)<br>From: "Attila Ondi" &lt;<a ymailto="mailto:aondi@fit.edu" href="mailto:aondi@fit.edu">aondi@fit.edu</a>&gt;<br>Subject: [clean-list] Question on destructive array updates<br>To: <a ymailto="mailto:clean-list@science.ru.nl" href="mailto:clean-list@science.ru.nl">clean-list@science.ru.nl</a><br>Message-ID:<br>&nbsp;&nbsp;&nbsp; &lt;<a ymailto="mailto:3441.163.118.203.36.1224270145.squirrel@webaccess.fit.edu" href="mailto:3441.163.118.203.36.1224270145.squirrel@webaccess.fit.edu">3441.163.118.203.36.1224270145.squirrel@webaccess.fit.edu</a>&gt;<br>Content-Type: text/plain;charset=iso-8859-1<br><br>Hi all,<br><br>I was trying to refresh my knowledge in Clean and picked to
 implement the<br>Fibonacci series.&nbsp; The obvious recursive implementation (Fib) was trivial<br>and then I tried to move on to use some tricks to speed up the<br>computation.&nbsp; The first idea was to use lists to store the already<br>computed values (Fib2).&nbsp; This worked, but did not prove any faster<br>(according to the profiler) mostly because of the many list traversals.<br><br>Then I tried my hands using arrays as I remembered they provide constant<br>access time to their elements and can also be updated destructively (to<br>avoid re-creating an almost identical array).&nbsp; The resulting function<br>(Fib3) is pretty similar to the one using lists (Fib2), but I cannot get<br>it to compile (complaining about type coercion in the line "| a.[n] &gt; 0 =<br>(a.[n], a)" in the function Fib3_ "Uniqueness error: attribute at<br>indicated position could not be coerced *(Int,^{u:Int})").&nbsp; No matter what<br>I tired (e.g. unnamed uniqueness
 type annotations, strict and/or unboxed<br>elements), I could not get rid of the compiler error.&nbsp; All&nbsp; my efforts to<br>find some explanation to the problem through web search were futile, so<br>I'd like to ask the list a few questions:<br><br>1) Why does the compiler (just downloaded the latest 2.2) present me with<br>an error when I don't reuse the array, only an element of it (or was<br>trying to at least) -- shouldn't possible multiple references be handled<br>properly by the runtime?<br><br>2) Can the calculation of the Fibonacci sequence be implemented with the<br>use of a destructive array?&nbsp; If yes how (or how to fix my program) -- if<br>not, why not?<br><br><br>And finally, here is my program.&nbsp; It also includes a linear calculation of<br>the Fibonacci numbers (Fib4) without using any array or list components<br>(just accumulators) for completeness -- I hope my email client does not<br>mess up the indentations too
 much.<br><br>Thanks,<br>Attila Ondi<br><br><br>=================<br>module Fibonacci<br><br>import StdEnv<br><br>Fib :: Int -&gt; Int<br>Fib 0 = 1<br>Fib 1 = 1<br>Fib n = Fib (n-1) + Fib (n-2)<br><br><br>Fib2 :: Int -&gt; Int<br>Fib2 n<br>| n &lt; 0 = abort "Fib2: Called with negative parameter"<br>| otherwise =<br>&nbsp;&nbsp;&nbsp; let<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (res, _) = Fib2_ n []<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fib2_ :: Int [Int] -&gt; (Int, [Int])<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fib2_ 0 l=:[x0 : xs] = (x0, l)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fib2_ 0 _ = (1, [1])<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fib2_ 1 l=:[x0, x1 : xs] = (x1, l)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fib2_ 1 _ = (1, [1, 1])<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fib2_ n l<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | length l &gt;= n+1 =<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; let<br>&nbsp;&nbsp;&nbsp;
 &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nth :: Int [Int] -&gt; Int<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nth 0 [x : _] = x<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nth n [_ : xs] = nth (n-1) xs<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; nth _ [] = abort "nth: Not enough elements in list"<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; in (nth n l, l)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | otherwise =<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; let<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (res1, resl1) = Fib2_ (n-2) l<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (res2, resl2) = Fib2_ (n-1) resl1<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; in (res1 + res2, resl2)<br>&nbsp;&nbsp;&nbsp; in res<br><br><br>Fib3
 :: Int -&gt; Int<br>Fib3 n<br>| n &lt; 0 = abort "Fib3: Called with negative parameter"<br>| otherwise =<br>&nbsp;&nbsp;&nbsp; let<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (res, _) = Fib3_ n (createArray n 0)<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fib3_ :: Int *{Int} -&gt; (Int, *{Int})<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fib3_ n a<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | size a &lt; n+1 = abort "Fib3_: Array is smaller than required"<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | a.[n] &lt; 0 = abort "Fib3_: Invalid array value"<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | a.[n] &gt; 0 = (a.[n], a)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | otherwise =<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; let<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (res1, resa1) = Fib3_ (n-1) a<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (res2, resa2) = Fib3_ (n-2)
 resa1<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; in (res1 + res2, resa2)<br>&nbsp;&nbsp;&nbsp; in res<br><br><br>Fib4 :: Int -&gt; Int<br>Fib4 n<br>| n &lt; 0 = abort "Fib4: Called with negative parameter"<br>| otherwise =<br>&nbsp;&nbsp;&nbsp; let<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (_, _, res) = Fib4_ n 1 1<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fib4_ :: Int Int Int -&gt; (Int, Int, Int)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fib4_ 0 tmp _ = (0, 0, tmp)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fib4_ 1 _ acc = (0, 0, acc)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Fib4_ n tmp acc<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | otherwise = Fib4_ (n-1) acc (acc + tmp)<br>&nbsp;&nbsp;&nbsp; in res<br><br>Start :: [Int]<br>Start = [Fib 7, Fib2 7, Fib3 7, Fib4 7]<br>=================<br><br><br><br><br>------------------------------<br><br>_______________________________________________<br>clean-list mailing list<br><a
 ymailto="mailto:clean-list@science.ru.nl" href="mailto:clean-list@science.ru.nl">clean-list@science.ru.nl</a><br><a href="http://mailman.science.ru.nl/mailman/listinfo/clean-list" target="_blank">http://mailman.science.ru.nl/mailman/listinfo/clean-list</a><br><br><br>End of clean-list Digest, Vol 47, Issue 10<br>******************************************<br></div></div></div><br>Send instant messages to your online friends http://au.messenger.yahoo.com </body></html>