Possible way to achieve lazy loading with const objects

Jonathan M Davis jmdavisProg at gmx.com
Mon Sep 26 12:27:16 PDT 2011


On Monday, September 26, 2011 12:02 Steven Schveighoffer wrote:
> On Mon, 26 Sep 2011 13:57:04 -0400, Jonathan M Davis <jmdavisProg at gmx.com>
> 
> wrote:
> > On Monday, September 26, 2011 10:26 Steven Schveighoffer wrote:
> >> On Mon, 26 Sep 2011 12:12:30 -0400, Jonathan M Davis
> >> <jmdavisProg at gmx.com>
> >> 
> >> wrote:
> >> > The point is that if aren't using immutable or shared, then you can
> >> > afford to
> >> > lazy load it, so you can wait to initialize the variable until it's
> >> > used, but
> >> > you _can't_ afford to do that in the case of immutable, because the
> >> 
> >> data
> >> 
> >> > must
> >> > be immutable and can't be changed later to do the lazy loading, and
> >> 
> >> you
> >> 
> >> > can't
> >> > afford to do that in the case of shared, because then you have
> >> > thread-safety
> >> > issues, so you have to pay the cost upfront in those cases.
> >> 
> >> It is only important that the value is constant *when it's read*, not at
> >> the beginning of the object existence. If you hook the only way to read
> >> it with a lazy initializer, then the two cases are indistinguishable, or
> >> using lazy initialization doesn't make sense.
> >> 
> >> Let's think of the case where *two* threads are lazily initializing an
> >> immutable struct. None of the members can be any different, because they
> >> are immutable, so if the value depends solely on the internal struct
> >> data,
> >> then both initializers will set the *Same value*. Two competing threads
> >> writing the same value do not result in corruption.
> > 
> > The problem with immutable is that it could (at least in theory) go in
> > read-
> > only memory, so lazy initalization doesn't work for it _at all_.
> 
> That is not a good reason :) Of course, any lazy initializers would have
> to be called during compilation time if the variable is put into ROM! Any
> lazy initializer that doesn't run during CTFE would result in a compiler
> error.
> 
> >> If the initializer depends on some *external state*, if that external
> >> state is also immutable, same result.
> >> 
> >> If the initializer depends on some external state that is *not*
> >> immutable,
> >> then why mark it lazy initialization? What is the point of initializing
> >> data that depends on something that's changing over time? I can't see
> >> the
> >> point of doing that. This is of course, only if you can't restart the
> >> initialization (i.e. clear the 'set' flag).
> >> 
> >> Note that if you want your proposed behavior you can achieve it by
> >> defining a constructor that eagerly initializes the variable by simply
> >> reading it.
> >> 
> >> I still don't think this proposal (even one that always lazily
> >> initializes) gives enough benefit to be included. Why would you want a
> >> constant lazily-initialized value in a non-immutable struct? If this
> >> were
> >> to mean anything, there would have to be a way to clear the 'set' flag
> >> in
> >> a mutable struct.
> > 
> > People have been complaining about the lack of logical const. The two use
> > cases that they seem to have been looking for are the ability cache the
> > results of member functions and to lazily load member variables. They
> > want to
> > be able to do those things with const and can't (in the case of Peter
> > Alexander, he seems to have come to the conclusion that it's bad enough
> > that
> > he doesn't use const for anything not related to threaings, though I do
> > find
> > that stance a bit odd, since it's _immutable_ that's needed for
> > threading, not
> > const). I was merely trying to present a solution to lazy loading that
> > worked
> > with const. It would therefore partially solve the issues that people
> > have
> > been complaining about.
> 
> Forgive me for objecting, but a lazy-initialization scheme that eagerly
> initializes isn't even a valid solution. I don't mean to be blunt, but I
> just can't put it any other way.
> 
> I see that you intended it to work lazily for non-const non-immutable
> items, but what would be the point then? I can implement lazy
> initialization on mutable types today.

No, I meant it to work for _const_ items. The entire point was to enable lazy 
initialization in objects which are mutable but passed to a function as const. 
As it stands, a const function can't do any kind of lazy initialization, so if 
you want to have lazy initialization, you can't use const. If _all_ you care 
about is lazy initialization, yes, you can do it just fine right now. The 
_entire_ point was to get it to work with const.

But since lazy initializion will _never_ work with immutable, it does eager 
initialization in that case, and yes that reduces the value of the solution, 
but that's life with immutable. But you still gain the benefit of having the 
lazy initialization with const objects, which was the entire point of the 
proposal.

- Jonathan M Davis


More information about the Digitalmars-d mailing list