DIP 1018--The Copy Constructor--Formal Review

Walter Bright newshound2 at digitalmars.com
Tue Feb 26 03:55:19 UTC 2019


On 2/25/2019 8:22 AM, H. S. Teoh wrote:
> I disagree.  Logical const means the outside world can't tell that the
> object has changed, because only a constant value is ever seen from
> outside.  This is the basis of lazy initialization (which is part of the
> concept of lazy evaluation), an important feature of FP style code, and
> something that D does not support.

We've been through the logical const discussion before. The problem with it is 
it is not machine checkable. Therefore it's a documentation thing, not a 
language thing.

The not-machine-checkable attributes should be in the domain of user-defined 
attributes. It's what they're for.


> A derived problem with D's const is the inability to express a cached
> const object.  You can't cache the object because it's const, which
> greatly limits the scope of usability of const in large data structures.

I'd like to draw a distinction between where one can USE const as apposed to 
where const has VALUE. I propose that weakening const so it can be used on data 
that is mutated anyway means it can be put to USE much more often, at a heavy 
price of a severely diminished VALUE. It's why I pressed Manu about the VALUE of 
head const.


> The same limitation makes ref-counting such a huge challenge to
> implement in D.  There is simply no way to associate a refcount with a
> const object without jumping through hoops and/or treading into UB
> territory by casting away const. There is no way to express that the
> refcount is mutable but the rest of the object isn't. Well, you *can*
> express this if you use circumlocutions like:
> 
> 	struct RefCounted(T) {
> 		int refcount;
> 		const(T) payload;
> 	}
> 
> but that's worthless in generic code because const(RefCounted!T) !=
> RefCounted!(const T). So you have to special-case every generic function
> that needs to work with this type, and the special cases percolate
> through the entire codebase, uglifying the code and forcing generic
> functions that shouldn't need to know about RefCounted to have to know
> about it so that they can work with it.

We're well aware of that issue. The lack of copy-constructors was the first big 
barrier to getting ref counting working properly.


> Because of these limitations, const is really only useful in low-level
> modules of limited scope, in simple, self-contained data structures.
> Higher-level, larger data structures are basically unusable with D's
> const because lazy initialization and caching are not possible without
> treading into UB territory by casting.  I'm not going to argue that
> C++'s version of const is any better -- because non-enforceable const is
> worthless, like you said -- but let's not kid ourselves that D's const
> is that much better.  D's const is really only usable in very limited
> situations, and there are many things for which it's unusable even
> though logically it *could* have been applicable.

We'll see. I've been slowly getting better at refactoring code so I can use 
const, and as I've recounted before, the results are quite pleasing.



More information about the Digitalmars-d-announce mailing list