Newbie question about automatic memoization

Does Haskell support any form of automatic memorization? For example, does the function iterate f x which expands to [x, f(x), f(f(x)), f(f(f(x))), … gets slower and slower each iteration, or can it take advantage of the fact that f is referentially transparent and hence can be "memoized / cached"? Thanks, Peter No virus found in this outgoing message. Checked by AVG Free Edition. Version: 7.5.476 / Virus Database: 269.10.25/926 - Release Date: 29/07/2007 23:14

On 7/30/07, peterv
Does Haskell support any form of automatic memorization?
For example, does the function
iterate f x
which expands to
[x, f(x), f(f(x)), f(f(f(x))), …
gets slower and slower each iteration, or can it take advantage of the fact that f is referentially transparent and hence can be "memoized / cached"?
Thanks, Peter
For 'iterate' the answer does not really need to be memoized. I imagine the definition of 'iterate' looks something like this: iterate f x = x : iterate f (f x) So f isn't being applied n times to x for the n+1st element, rather, it's being applied once to the nth element for the n+1st element. Bryan

Bryan Burgers wrote:
On 7/30/07, peterv
wrote: Does Haskell support any form of automatic memorization?
For example, does the function
iterate f x
which expands to
[x, f(x), f(f(x)), f(f(f(x))), …
gets slower and slower each iteration, or can it take advantage of the fact that f is referentially transparent and hence can be "memoized / cached"?
Thanks, Peter
For 'iterate' the answer does not really need to be memoized.
Or, another way of phrasing that answer is 'yes'. The definition of iteration does memoize - although normally one would say 'share' - the intermediate results.
I imagine the definition of 'iterate' looks something like this:
iterate f x = x : iterate f (f x)
Haskell doesn't automatically memoize. But you are entitled to assume that named values are 'shared' rather than calculated twice. For example, in the above expression "x", being a named value, is shared between (a) the head of the list and (b) the parameter of the function "f" inside the recursive call to iterate. Of course sharing "x" may not seem very interesting, on the outermost call, but notice that on the next call the new "x" is the old "f x", and on the call after that the new "x" is "f (f x)" w.r.t the original "x". Jules

Thanks! Is this is also the case when using let and where, or is this just syntactic sugar? -----Original Message----- From: Jules Bean [mailto:jules@jellybean.co.uk] Sent: Tuesday, July 31, 2007 5:09 PM To: Bryan Burgers Cc: peterv; haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] Newbie question about automatic memoization Bryan Burgers wrote:
On 7/30/07, peterv
wrote: Does Haskell support any form of automatic memorization?
For example, does the function
iterate f x
which expands to
[x, f(x), f(f(x)), f(f(f(x))), .
gets slower and slower each iteration, or can it take advantage of the fact that f is referentially transparent and hence can be "memoized / cached"?
Thanks, Peter
For 'iterate' the answer does not really need to be memoized.
Or, another way of phrasing that answer is 'yes'. The definition of iteration does memoize - although normally one would say 'share' - the intermediate results.
I imagine the definition of 'iterate' looks something like this:
iterate f x = x : iterate f (f x)
Haskell doesn't automatically memoize. But you are entitled to assume that named values are 'shared' rather than calculated twice. For example, in the above expression "x", being a named value, is shared between (a) the head of the list and (b) the parameter of the function "f" inside the recursive call to iterate. Of course sharing "x" may not seem very interesting, on the outermost call, but notice that on the next call the new "x" is the old "f x", and on the call after that the new "x" is "f (f x)" w.r.t the original "x". Jules

Hello peterv, Tuesday, July 31, 2007, 11:06:23 PM, you wrote: it is property of explicit *name* given to result of some expression. for example, when you write f x = g (x*x) (x*x) result of x*x isn't stored because it may be very large and compiler exactly follows your instruction - "calculate x*x two times" without trying to do optimization that may turn out to pessimization (of course, i mean that with *lazy* evaluation x*x is calculated only when needed and it may become a pessimization to save value between its usages as first and second argument) when you write f x = g t t where t=x*x compiler gets an instruction to calculate x*x only once and share calculated value between two parameters and it does just what you said
Thanks! Is this is also the case when using let and where, or is this just syntactic sugar?
-----Original Message----- From: Jules Bean [mailto:jules@jellybean.co.uk] Sent: Tuesday, July 31, 2007 5:09 PM To: Bryan Burgers Cc: peterv; haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] Newbie question about automatic memoization
Bryan Burgers wrote:
On 7/30/07, peterv
wrote: Does Haskell support any form of automatic memorization?
For example, does the function
iterate f x
which expands to
[x, f(x), f(f(x)), f(f(f(x))), .
gets slower and slower each iteration, or can it take advantage of the fact that f is referentially transparent and hence can be "memoized / cached"?
Thanks, Peter
For 'iterate' the answer does not really need to be memoized.
Or, another way of phrasing that answer is 'yes'. The definition of iteration does memoize - although normally one would say 'share' - the intermediate results.
I imagine the definition of 'iterate' looks something like this:
iterate f x = x : iterate f (f x)
Haskell doesn't automatically memoize. But you are entitled to assume that named values are 'shared' rather than calculated twice. For example, in the above expression "x", being a named value, is shared between (a) the head of the list and (b) the parameter of the function "f" inside the recursive call to iterate.
Of course sharing "x" may not seem very interesting, on the outermost call, but notice that on the next call the new "x" is the old "f x", and on the call after that the new "x" is "f (f x)" w.r.t the original "x".
Jules
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

peterv
Does Haskell support any form of automatic memorization?
I used a C compiler in the 1980's that would routinely put values into registers that were already there, so I'm deeply suspicious in ways that turn out to always be completely unwarranted for GHC. Nevertheless, there is no better way to understand what a compiler does than to make experiments. One thing that profiling does with GHC is count entries into a function. You can use this for example to determine which way case statements are usually branching; just make dummy functions (f x = x, not f = id) to pass each value through, and look at the counts. In answer to your question, much depends on whether optimization is turned on or off. If f x $ g y is executed repeatedly for a fixed value of y, one sees equal counts for f and g with optimization off. With optimization on, g gets called once. Try to dissect your own situations this way (or better ways that others are about to chime in with...) It's fun. The usual cycle is "Gee, they can't have been clever enough to have provided for this obscure scenario... Click, click, ... click, click. Oh. They were."
participants (5)
-
Bryan Burgers
-
Bulat Ziganshin
-
Dave Bayer
-
Jules Bean
-
peterv