On Mon, 26 Sep 2011 12:12:30 -0400, Jonathan M Davis <jmdavisp...@gmx.com> wrote:

On Monday, September 26, 2011 08:01:29 Steven Schveighoffer wrote:
On Sat, 24 Sep 2011 00:11:52 -0400, Jonathan M Davis <jmdavisp...@gmx.com>

wrote:
> Okay. I'm not saying that we should necessarily implement this. I'm just
> looking to air out an idea here and see if there are any technical
> reasons why
> it can't be done or is unreasonable.
>
> Some programmers have expressed annoyance and/or disappointment that
> there is
> no logical const of any kind in D. They generally seem to be trying to
> do one
> of two things - caching return values in member functions or lazily
> loading
> the values of member variables.

The major reason for having logical const is to a) store state on the
object that is not considered part of the object, or b) store references
to objects that are not part of the object state.

For example, storing a reference to a mutex in an object, or a reference
to an owner object.  It's the difference between a "has a" relationship
and a "points to" relationship.

Your lazy loading idea does not help at all for these.

I believe that the two main complaints about the lack of logical const which
have been coming up in the newsgroup have been the inability to cache the
return values of member functions and the inability to lazily load the values
of member variables. This is simply an attempt to solve the lazy loading
portion of that problem.

Of course. My point was that your two use cases I think are far less used than the refer-to-other-object-but-don't-own-it cases.

Maybe I'm wrong, it's been a long time since I used C++, and mutable in general. But I remember using it when I wanted to have a reference to something that was not part of the object.

> 6.  If the S being constructed is shared or immutable and __varProp is
> not
> called in the constructor, then __varProp is called immediately after
> the
> constructor (or at the end of the constructor if that works better for
> the
> compiler).

Why? What if the calculation is very expensive, and you never access var?

Besides, we can already pro-actively initialize data in an immutable
constructor, what is the benefit here?

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.

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.

-Steve

Reply via email to