<div class="gmail_quote">On 23 November 2011 21:21, Peter Alexander <span dir="ltr"><<a href="mailto:peter.alexander.au@gmail.com">peter.alexander.au@gmail.com</a>></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 23/11/11 6:10 PM, Manu wrote:<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
        Perhaps if you declared some function as lazy, then the compiler<br>
        would<br>
        be expected to cache the return value<br>
<br>
<br>
    How does it cache it?<br>
<br>
    i.e.<br>
<br>
    - What data structure does it use?<br>
    - Is there a size limit, or does it just keep adding into the cache<br>
    until you run out of memory?<br>
    - What allocator does it use?<br>
    - If there is a size limit, what is the eviction policy?<br>
    - and what is the size limit?<br>
    - How do I manually flag the cache as dirty if I want to clear it?<br>
<br>
    There is no automatic way to do caching. Every single application of<br>
    caching has its own needs and you need control over that. You can't<br>
    just stick it all in a hash table and be done with it.<br>
<br>
<br></div><div class="im">
I can imagine many possibilities. Here's one straight off the top.<br>
<br>
- The data structure is the return value of the function contained<br>
within its parent class/struct + any necessary dirty bits. Where you<br>
place those it in the containing class/struct is debatable, but sensible<br>
options exist.<br>
</div></blockquote>
<br>
This simply doesn't work for functions of arguments that require caching.<br>
<br>
class FooManager<br>
{<br>
    class Foo { ... }<br>
<br>
    const(Foo) getFoo(int i) const<br>
    {<br>
        return new Foo(i);<br>
    }<br>
}<br>
<br>
Assume that constructing a Foo is expensive. How can I cache the values of Foo? One approach would be to use an array:<br>
<br>
class FooManager<br>
{<br>
    class Foo { ... }<br>
<br>
    const(Foo) getFoo(int i) const<br>
    {<br>
        if (m_foos[i] is null)<br>
            m_foos[i] = new Foo(i); // illegal in D<br>
        return m_foos[i];<br>
    }<br>
<br>
    const(Foo)[kCacheSize] m_foos;<br>
}<br>
<br>
Of course, this requires knowledge of the range of 'i' that can be received, so there is no way to automate this type of caching.<br>
<br>
You could automatically use a hash map, but that is needlessly inefficient. Also, what if getFoo could be called with any value of i? You wouldn't want to cache all values, you'd just want to cache a subset using some eviction policy, perhaps the 10 most recently used values of 'i'?<br>

<br>
There's no way to automate caching. One size does not fit all.</blockquote><div><br></div><div>This isn't a typical lazy evaluation. In your example, the problem exists irrespective of the const implementation. I don't think it addresses the topic.</div>
<div>I'm talking about calls to the same function returning same result every time. So yes, functions with no arguments.</div><div>I can sort of imagine it might be possible to implement my proposal though even in your case where it receives an index and internally chooses from a set (each having their own associated dirty flag), but where it uses an argument to produce the output that may change every time... this is not lazy evaluation, it's functional evaluation.</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
- Size limit? What is the size limit of the object returned from the<br>
function in the first place?<br>
- Not really relevant, if it's a primitive type or struct, it is<br>
contained by the functions containing object, if it is a class, then it<br>
is a reference to, and it is allocated however the lazy function does.<br>
- I don't think this is relevant.<br>
- Again...<br>
- Fair question. Perhaps the function could have a property, or the<br>
containing class could have some property to access the cached object...<br>
but I would imagine the compiler would explicitly manage dirtying of the<br>
state, so that it can enforce that it is done in a '@safe' way...<br>
</blockquote>
<br></div>
All these responses assume that the function is not a function of its arguments (or it has no arguments).</blockquote><div><br></div><div>Correct. Lazy/cached evaluation of some slow method.</div><div><br></div><div><br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Am I wrong in suggesting that this is the most frequent cause of people<br>
raising the "D const issues' topic?<br>
</blockquote>
<br></div>
Yeah, it usually comes down to caching (or lazy computation, which is similar) but it's not the only thing.<br>
<br>
Essentially, any object that contains state that is not related to its definition of equality is difficult to model using D's const qualifiers.<br>
</blockquote></div><br>