Fully transitive const is not necessary

Janice Caron caron800 at googlemail.com
Wed Apr 2 01:14:28 PDT 2008


On 01/04/2008, guslay <guslay at gmail.com> wrote:
>  -= A const method may exhibit side effects =-

There is really no such thing as a const method. What we /call/ a
const method is just a function, like any other. In any function, some
parameters may be const, others not. In what you call a "const
method", the hidden variable "this" is typed const - but that has no
impact on any other function parameter, nor on any other variable in
scope. In fact, I could even do

    class C
    {
        int x;

        void f(C c) const
        {
            ++c.x;
        }

        void g()
        {
            f(this);
        }
    }

and have f() modify a member variable, despite being declared const,
simply by doing it through another pointer.

So, while what you say is true, it's nothing but a statement of the
obvious. It's /how things are supposed to work/. If you have any
expectation that things are supposed to behave differently, then you
just haven't understood what a const member function is.



>  The transitivity of const does not extends beyond the scope of the class.

It would be more accurate to say that the transitivity of const(T)
does not extend beyond that which is reachable through T. But T
doesn't have to be a class.


> You may call static/global functions and modify static/global data, modify mutable objects accessible through static/global pointers, perform I/O, etc.

Of course. Again, you're stating the obvious.


>  -= Const != thread-safe =-
>
>  A method with potential side effects is not implicitly thread-safe.

Again with the obvious. Is there any point to this? Are you somehow
suggesting that anyone on this newsgroup believes otherwise?


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

Yes it is. But const is /part/ of the solution, not the /whole/ of the
solution. Saying "const is not the key to functional programming" is a
bit like saying "wheels are not the key to making cars". Well, it's
true that wheels aren't /enough/ to make a car - an engine would help,
for as start - but they do matter. It would be a tough job making a
car without wheels. And likewise it would be a tough job making
functional programming work without (transitive) const.


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

I don't understand that sentence. Why is the word mathematical in
quotes? I hope you're not suggesting that mathematics is a dodgy
discipline, because it's probably the /only/ discipline in the
universe which offers solid proofs for its theorems. Even ignoring
that, I have no idea what you're trying to say here.


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

That sounds reasonable, though it should really say /transitive/ invariant data.


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

OK.


>  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.

INCORRECT. A pure function cannot read static or global data, period.



>  -= 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.

No it isn't.


>  Sure, the bits of the object cannot change, but since /everything else/ can change,
 the "purity" of constness

Const doesn't claim to be pure.


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

On a variable by variable basis, yes. /That's what const means/.


> 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;

The bottom line is that any class which is not /truly/ const, (as in
physically, not merely logically), cannot be passed to any function
which modifies the mutable parts, and simultaneously stay thread-safe.


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

And their code won't be thread-safe.


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

I'm afraid it does. A type with mutable members can never be cast -
either implicitly or explicitly - to fully const. That breaks
everything.


>  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).

Really?

    class C
    {
        int x;
        mutable int y; // just pretend this is legal
    }

    void f(const(C) c)
    {
        int temp = y;
        y = temp + 1;
    }

Now imagine two threads calling f simultaneously with the same c.
Imagine a thread switch occurs between the two statements.



>  -= Mutability is required =-

Mutability, you have. It happens when you don't declare a thing const.


>  An object is fully initialized, but some parts are lazyly evaluated and require mutable members.

Then it isn't const.


>  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.

There are trivial workarounds. Instead of

    class C
    {
        int x;
        mutable int y;
    }

    void f(const(C) c);

just do this:

    class C
    {
        int x;
    }

    class D
    {
        int y;
    }

    void f(const(C) c, D d);

This is just a simple matter of saying what you really mean.


>  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.

...or it might be screwed up entirely as a result of a threading conflict.



More information about the Digitalmars-d mailing list