Why D const is annoying

Chris Cain clcain at uncg.edu
Wed May 2 13:12:39 PDT 2012


On Wednesday, 2 May 2012 at 15:35:15 UTC, Mehrdad wrote:
> I guess this answers my question then: const/immutable are 
> useful for multithreading.

Indeed, const/immutable makes multithreading much better. It
provides restrictions which make it much easier to think about
problems. If I pass a const reference into a function, I can be
guaranteed it won't be changed by that function.

> So it means, essentially, they're pretty useless for Objects, 
> but only useful for structs.
> Why? Objects have **behavior** (not just data) ...

Structs in D have behavior as well. In fact, I've found most
things I might be forced to use objects/classes in most other
languages can be easily done with D's structs and all of the
behavior and state is encapsulated nicely. Combine that with
templates and you've got some ridiculous power and efficiency.

> Sure, the method writer can call the method 'const', but he 
> really has no idea whether someone will override it down the 
> road and get struck by lightning because of that.

If the method writer has the method be const, then he's said that
the contract of that method is that it doesn't change the
object's state. This is no different than having a method that
takes a string and complaining that the method writer has no idea
whether someone will want to override it later and want the
method to take an int.

You can overload the method to take an int. And you can overload
the method later down the line so that you have an implementation
which does mutate state and isn't const. Although, you certainly
need to have a version which doesn't mutate state available
still. But that's just part of the contract.

If you're writing a method and you've decided "I want whoever
uses this method to not cause any mutation of state when they
call this method" (maybe so there's a guarantee of consistency in
execution speed between calls or something), then you mark it
const. Otherwise, it's not really a const method.

> Because of that, I think we disallow direct instantiation of 
> const() or immutable() Objects altogether, because they're 
> pretty useless.

Why? There's no reason to throw the baby out with the bath water.
There's plenty of need for inheritance for immutable/const
representation of data. Just because we can't use it for objects
whose whole life is caching (which is a clear subset of OOP usage)
doesn't mean it's useless.

> Huh? Not if they're instance variables.
> It's kind of silly to lock against something so you can modify 
> instance variables.

Depends. If you're just accessing the instance method directly
(and it's an atomic operation), you can get away with not locking.

However, If you have a C++ const object and you call a getter
method on it in a context where someone else may also be calling
a getter method on it, you must lock it. By your own admission,
you can't depend on implementation of the object. Ergo, the
getter methods may be mutating state (you can't assume it's not),
and you can't tell whether or not they are because const in C++
doesn't say whether it will mutate state. Of course, if you don't
depend on the correctness of the method you're free to not lock...

In D, if I'm sure these const objects aren't being modified
elsewhere, I can absolutely get away with not locking when I call
getter methods. If it's an immutable object, it doesn't even
cross my mind whether I need to lock it or not. You don't have
that kind of peace of mind in C++.


> I don't think I ever violated C++'s 'const'... (?)

Well, seeing as C++ const apparently has no meaning ... it's
rather hard to "violate" it, per say. Honestly, the time my
professors taught me about C++'s const, they said it was for
methods that don't modify state. Evidently that wasn't the case,
but I never got into the mindset that const didn't mean something
that doesn't modify state... so it's rather hard for me to think
of a reason to use const for this. Const to me has always meant
"don't mutate state." If you just want a view of the object where
you only use getters, that's really what D's interfaces are for.

> More like, a **CHECKED** comment.
> Big difference.

Not exactly. It's not "checked" because const objects can be
changed by anyone at anytime easily and it's common and the
compiler doesn't care. It doesn't mean anything.

Again, what I think you actually want is an interface of the
getters, not const. There's no sense in having both do the same
thing when we can actually use const to mean an object that you
won't mutate.

=-=-=-=

In any case, would the Student-getter style interface method work
for this use case or not?

interface IStudentRO {
     string getName();
     string getAddress();
     real getGPA();
     ...
}

class Student : IStudentRO {
     IConnection conn;
     string name;
     ...
     string getName() {
        if(!name)
           name = conn.get("name");
        return name;
     }
     ...
     void setName(string newName) {
        name = newName;
        conn.set("name", newName);
     }
     ...
}

void process1(IStudentRO student); // Compile-time checking ...
can only use getters.


More information about the Digitalmars-d mailing list