Transitive const sucks

Sean Kelly sean at f4.ca
Wed Sep 12 15:41:47 PDT 2007


Janice Caron wrote:
> On 9/12/07, Walter Bright <newshound1 at digitalmars.com> wrote:
> 
>> Because multithreaded programming doesn't start working if the interface
>> hides the changing variables. If it did, parallel programming would be
>> easy. Logical constness is *still* changing state, and since it is, all
>> the boogeymen of synchronization, race conditions, deadlocks, etc., are
>> all there.
> 
> I've written a lot of multithreaded programming. A lot.
> 
> ...which is perhaps a bad thing, because sometimes I forget that D
> does things differently. I don't need to use a separate mutex class if
> you've got synchronized.

In general that's true, though you might want a separate mutex class for 
specialized needs: inter-process synchronization, etc.

> (By the way - could you also allow the spelling "synchronised" for the
> benefit of speakers of British English?) :-)
> 
> synchronised is a blunt tool though. In my C++ code, I arrange it so
> that multiple threads can simultaneously obtain read-access, or
> exactly one thread can obtain write-access. Correct me if I'm wrong,
> but the built-in synchronized feature isn't that smart?

Yes and no :-)  The default implementation isn't that smart, but it can 
be extended.  Tango has a ReadWriteMutex that works like so:

     auto readWriteLock = new ReadWriteMutex;

     synchronized( readWriteLock.reader )
     {
         // any number of threads can be here simultaneously
     }
     synchronized( readWriteLock.writer )
     {
         // only one thread may enter this block simultaneously
         // and no threads may be in the reader block above either
     }

> So anyway, as I mentioned further up this thread, I had this loopup
> class member function that got stuff from a file and cached it. I
> assure you it was thread-safe. It even allowed multiple readers (if
> the key/value pair was already cached), but if a lookup was not
> cached, one thread and one thread only got to open the file, read a
> chunk of data, and stick it in the file. This was a class that knew
> what it was doing.
> 
> You're probably going to tell me that I can still do all that in D,
> providing I don't declare it const. The problem is, if I don't declare
> it const, /and/ all consts in D are transitive, then I can't store a
> reference to that object in any const structure. Basically I'd end up
> declaring just about nothing const, and I'd see no benefit.

I've been wondering about this.  So far, I've only been able to come up 
with two options:

1) Cast away const when dealing with 'mutable' data.
2) Store mutable data externally, perhaps in an AA.

I haven't yet decided whether there are any fundamental problems with 
option 1 other than it being generally bad practice.  Option 2 seems 
impractical in most cases however, because any common store of such 
mutable data must itself be protected by a mutex.

>> Very few programmers are able to successfully write such
>> code. With FP programming, most programmers will be able to.
> 
> That's obviously true. I'm not sure why it's relevant though. You said
> you had a "pure" keyword in mind for that. But if I don't use the pure
> keyword, then thread safety should be down to me, right?

I think Walter is suggesting that the language should still lend itself 
to code that isn't error-prone.  What remains unclear to me is whether 
the lack of 'mutable' will actually be an issue or if workarounds and 
alternate programming techniques (encouraged by the FP model) will be 
sufficient as a replacement.

>> It has come up before. The answer is to not declare logically const
>> things as being const, because they aren't const. Logical constness
>> belongs as a comment because it is not compiler checkable.
> 
> But you might want to declare logically const things as being const
> for efficiency reasons. And to argue that "they aren't const" is a
> matter of definition. "const" in C++ is /defined/ to mean logical
> const, so const they are! You use the word to mean "physically const".
> We don't all agree on the definition.
> 
> Suppose there exists a class String with member function uppercase(),
> declared const (or invariant, as you would have it in D). So far, so
> good.
> 
> But then, along comes a better (or at least, different) string class
> with the same interface, and it happens to be faster, and I want to
> use the new FastString class in place of the old String class. All I
> have to do is search and replace, right? Or just make an alias. But
> there's a problem. Turns out, the reason it's faster is because it
> caches some results internally so it doesn't have to keep recomputing
> them.
> 
> From the point of view of "implementation should be independent of
> interface" this internal detail is something I shouldn't need to know
> or care about.
> 
> But now suddenly, I do need to know about it. And care. Because now
> that uppercase() function I mentioned earlier is no longer physically
> const. That means, if I use it as a drop-in replacement, my code now
> won't compile.

That's a good example.  I do wonder, however, whether such an object 
would be a viable drop-in replacement in all cases.  In C++ my answer 
would be a confident "yes," but in D...

>> I'll reiterate that const-that-isn't-checkably-constant has no value
>> beyond being a comment, so it might as well just be a comment.
> 
> Oh contraire. It /is/ meaningful. It is a cast iron guarantee that no
> non mutable (which I argue should imply non-private) variables will be
> modified. Without the const declaration, you do not have that
> guarantee. It's a guarantee *which the compiler can use* to help the
> programmer catch errors!

Agreed.  Though I do think it's worth experimenting a bit more with the 
D approach to see if it is a reasonable replacement.  I do think that 
the traditional OO design that logical const supports in C++ may end up 
not being the general approach to program design in D.  But by the same 
token, perhaps that isn't sufficient reason to not support the approach.


Sean



More information about the Digitalmars-d mailing list