Fully transitive const is not necessary

guslay guslay at gmail.com
Tue Apr 1 12:00:15 PDT 2008


Steven Schveighoffer Wrote:

> I have been reading through the reddit posts about the const faq, and also 
> some posts here by guslay, and I believe Walter needs to re-think his 
> beliefs about how transitive const is necessary for the future.
> 

I'm glad to see this issue catch on. I'll try to summarize of the thoughts on const (in reality, invariant) expressed by others and myself.


-= A const method may exhibit side effects =-

The transitivity of const does not extends beyond the scope of the class. You may call static/global functions and modify static/global data, modify mutable objects accessible through static/global pointers, perform I/O, etc.



-= Const != thread-safe =-

A method with potential side effects is not implicitly thread-safe.



-= Const is not the key to functional programming =-

Immutability is required for FP, but const "mathematical" guarantees are too weak to provide that ability.



-= Pure function + invariant data is required for FP =-

As many have pointed out, the expected pure function will enable FP.

This concept is not yet into place, but I will define it has a method that only call other pure functions, and performs read-only operation on its class members and static/global data. In other terms, a method with no side effect, that can only modify its input and output.

A pure method is const, but a const method is not pure.



-= Const is part of the interface, not part of the implementation =-

Const part of the interface: you need to have a const method to call on a const object.

It is also an abstraction. In some sense, D const is already logical const. Sure, the bits of the object cannot change, but since /everything else/ can change, the "purity" of constness is defined by the implementation. In other words, const is a conceptual.

It does not mean that it is useless or without teeth, because D const is enforceable (but only on a member-by member basis).

Defining const as bitwise const for the whole object is simplistic. You can still (imperfectly) fake mutability. Allowing this would be desirable.

   class MyMutableClass
   {
      private         int normal_part;
      private mutable int mutable_part;

      public int const lazyGetter();
   }

   const MyMutableClass obj = new MyMutableClass;

If not, people will find a way to hack around it with ugly tricks.

   int mutable_part;

   class MyHackishClass
   {
      private         int normal_part;
      public int const lazyGetter();
   }

   const MyHackishClass obj = new MyHackishClass;


Mutable is an acknowledgment of the current limits of const.



-= Allowing mutable members does not break or weaken the const model =-

D const is powerful because it is enforceable.

What mutable does is allowing finer-grained control over the powerful const system. It does not weaken it, it controls its scope. Those are orthogonal issues (as far as I have yet to see an instance where having half the fields of an object const, instead of all the fields of the object, limits anything in any way).

The internal state of the object will not be modified beyond what the class designer intended and allowed. The extent of const should be an implementation detail.



-= Mutability is required =-

C++ mutable keyword is not strictly required. Given that constness is almost never enforced in practice, one can cast away constness, modify "constant" data, and move on. Mutable offers a cleaner way to do that in the clear, as part of the class definition.

The casting trick cannot be used in D (gladly).

But which is worst?

An object is fully initialized, but some parts are lazyly evaluated and require mutable members. The object as to be sent to an external entity.

a) Mutable members are not allowed. The object cannot be passed as const. The non-const object is passed to the external function, renouncing to any control at all on the immutability of the object.

b) Mutable members are allowed. The object is passed as const. The caller can be confident that the internal state of the object will not be modified beyond the intention of the class designer.

Mutable strengthen the const system.






More information about the Digitalmars-d mailing list