<div class="gmail_quote">On Mon, Sep 14, 2009 at 1:49 PM, Wesley W. Terpstra <span dir="ltr"><<a href="mailto:wesley@terpstra.ca">wesley@terpstra.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="gmail_quote"><div class="im">On Sun, Sep 13, 2009 at 9:49 PM, Wesley W. Terpstra <span dir="ltr"><<a href="mailto:wesley@terpstra.ca" target="_blank">wesley@terpstra.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="gmail_quote"><div> Does it have exponential complexity in the number of variables?<br></div></div></blockquote></div><div><br>The answer to this question appears to be: YES!<br><br>I've found a point in my project where adding one element to the record (more than) doubles the compile time. I'm using the FunctionalRecordUpdate pattern with this record. At this point my compile times have gone up to 25 minutes on the fastest computer available to me (my laptop now takes 1.4 hours)... It had 22 elements for a compile time of 10:30 minutes then I increased it to 23 elements (plus some code to force the element to be used) and the compile time went up to 24:46 minutes<br>
<br>At least now that I know what causes the problem, I can work around it, but it seems pretty unfortunate that MLton has an exponential time liveness calculation. Can this be fixed?<br></div></div></blockquote><div><br>
Good lord. Don't blame MLton, blame sweeks and vesa!<br><br>The FunctionalRecordUpdate on the wiki has exponential type explosion. This makes it pretty useless in practice. Also, the code size still grows quadratically due to the list of 'A's that one has to make. <br>
<br>I've made a work-alike version that has linear code growth and no explosion. This is it:<br>(* Briefly, if you have a record { foo: int, bar: real, baz: word }...<br> * fun updateRecord z =<br> * let<br> * fun from v1 v2 v3 = {foo = v1, bar = v2, baz = v3}<br>
* fun to f {foo = v1, bar = v2, baz = v3} = f v1 v2 v3<br> * in<br> * makeUpdate3 (from, from, to) z<br> * end<br> *<br> * You can then update records with: updateRecord record (set#bar 1.0) $<br> *)<br>
structure FunctionalRecordUpdate =<br> struct<br> local<br> (* The user supplies us with these two functions:<br> * to f { a, b, c } = f a b c<br> * from a b c = { a, b, c }<br> *<br>
* The goal is to create a family of functions like:<br> * f0 (f, z) a b c = f (z a) b c<br> * f1 (f, z) a b c = f a (z b) c<br> * f2 (f, z) a b c = f a b (z c)<br> *<br>
* These functions are passed as arguments via selector:<br> * c3 g = g f0 f1 f2<br> *<br> * We can thus set g=from to get a record of functional updates.<br> * Use the update function as: to (record, upd (from, z))<br>
*)<br> <br> <br> fun next g (f, z) x = g (f x, z)<br> fun f1 (f, z) x = f (z x)<br> fun f2 z = next f1 z<br> fun f3 z = next f2 z<br> fun f4 z = next f3 z<br>
fun f5 z = next f4 z<br> fun f6 z = next f5 z<br> fun f7 z = next f6 z<br><br></div></div>