On Fri, 14 Feb 2014 23:03:50 -0500, Adam D. Ruppe
<destructiona...@gmail.com> wrote:
D doesn't have logical const, but sometimes it is useful, especially
with lazy initialization of a field, and we can kinda fake it with casts
or with global variables. Modifying an immutable object is undefined
behavior, so how can we avoid that, and if not, try to minimize the
problems in practice?
Using global variables to store local state is kinda silly, it seems to
me that doing a AA lookup kinda defeats the point of caching in the
first place, so I want to focus on the cast method.
So:
* should we always wrap the write in a synchronized block to minimize
the chances that we'll have thread problems with implicitly shared
immutable things passed as const? What's the best way to do this btw?
As a start, I would take a look at the code that generates the mutex when
you synchronize an object. It is the only case where logical const is
allowed in D.
* should objects with logical const methods deliberately not provide
immutable constructors to prevent them from being immutable? Would this
actually work?
This is a good idea. Can you @disable the immutable constructor?
* Anything else that is likely to come up?
Where you must be very very cautious is immutable pure functions. The
compiler may make assumptions that are not correct in terms of shortcuts.
My advice is to never change "logical const" data inside a const pure
function.
Other than that, depending on the use case, use C threading rules when
making changes. Basically, if you know the object will never be referenced
in multiple threads (very application specific), then you are OK to just
change it. Otherwise, I'd put a mutex on it, or (ironically) use the
object's monitor to protect it.
-Steve