== Quote from Marco Leise (marco.le...@gmx.de)'s article
> Am 02.08.2011, 01:51 Uhr, schrieb Walter Bright
> <newshou...@digitalmars.com>:
> > I've talked to many people who use logical const extensively in C++, and
> > really want it. If you dig down into what's happening, you'll find that
> > logical const isn't actually supported by C++. It's a convention.
> > There's simply nothing in the language that enforces that convention.
> >
> > The reason "logical const" does not work with const in D is because D
> > actually enforces const semantics, and relies on that enforcement.
> >
> > Since logical const is a convention in C++ anyway, you can have logical
> > const in D, too. Just put in a comment:
> >
> >     struct S /* This struct is logical const */
> >     { ... }
> >
> > and then follow the convention just as you would with C++.
> >
> > Const in C++ is not powerful - it's simply a fraud - and the two get
> > confused.
> I can understand the point of view of the compiler developer and I don't
> question that D const has advantages. It is definitly good to have
> transitive const in some use cases. Until today I didn't even know about
> logical const. But the more I think about it and its applications it looks
> like a valuable feature.
> I'm a typical OOP programmer and I generally avoid pointers where possible
> and use encapsulation - that is - mark methods and data fields private.
> But there are these strong cases where you cannot afford to have the usual
> transitive const. Instead you really want a high-level logical const. One
> that makes no sense to the compiler and is a 'fraud'. That is in OOP you
> give away a const reference to some object, meaning that the outside world
> cannot modify it logically. The encapsulated inner state though should not
> be affected by this.
> The example with the Matrix class is an excellent example. Here the
> programmer wants to make sure that the owner of the Matrix can safely give
> away that Matrix object without having to worry that the logical state
> changes, i.e. the mathematical representation changes. This is the
> 'caching' use case.
> Another one I've found is object composition:
> http://en.wikipedia.org/wiki/Object_composition#UML_notation
> The motor in your car: If the car is a const reference the motor has to be
> protected by that as well (composition).
> But if I call car.getVendor() I expect the mutable instance of the vendor
> object to call car.getVendor().buy(car.getModel(), 10) for my company's
> car pool.
> On this higher level C++ gives the form of logical protection for the
> 'caching' case that I need as an OO programmer.
> - Marco

The problem as I see it is that D has two separate concepts that are conflated:
const and immutable. In fact, I'd argue that immutable shouldn't even exist in 
its
current standalone state but should rather be part of an ownership system a-la
Bartosz' suggested annotation system.

In the context of single threaded programs const mustn't be transitive.
E.g.
class Foo { int a; ... }
class Bar { Foo foo; ...}
void func(const Bar b);
void gunc(immutable Bar b);

func should be able to change b.foo.a but not b.foo (foo is head-const or 
"final")
gunc however will enforce transitivity and will not allow to change b.foo.a

In the context of multi-threaded programs, casting const(T) to an immutable(T)
would require locking/synchronization in order to preserve correctness.

To conclude, Instead of D's current model where both T and immutable(T) can be
"up-casted" to const(T) I'm suggesting
T -> const(T) -(locked)-> immutable(T)

In addition, compile-time "manifest" consts via enum should be removed in favor 
of
immutable.

Reply via email to