On Mon, Oct 20, 2014 at 06:38:11PM -0700, Jonathan M Davis via Digitalmars-d wrote: [...] > Yeah. Ref-counting and const do not mix in D. The ref-counting would > violate const unless it's in a wrapper object or in a table somewhere. > The wrapper fails as soon as it ends up being const (either directly > or because it's inside of another object that's been marked const). > And having a table somewhere outside the object or any wrapper makes > it so that it doesn't work with pure. There are some serious, > practical downsides to transitive, physical const like D has. And I > don't think that any of us really know yet where the line is between > where const should and shouldn't be used. Too often, the solution is > to use it everywhere or to use it nowhere. And some folks violate it > and try and make it more like logical const (e.g. as I understand it, > vibe.d does ref-counting with const objects by casting away const and > then mutating the ref-count, which is definitely a risky thing to be > doing and arguably should never be done - but with the strong > restrictions of D's const, it's exactly the sort of thing that people > are going to be tempted to do). [...]
I've run into this before, and I've been thinking about whether it would help for the language somehow to support tail-const of wrapper types, such that: /* Note: this is hypothetical syntax */ tail_const(Wrapper!T) x; gets translated to: Wrapper!(const(T)) x; While this can already be manually done now, having it as a keyword (or otherwise dedicated syntax) allows things to work transparently, so that generic code never has to worry about what kind of wrapper(s) may be present in a user-passed object. If used with a reference type, tail_const behaves like Rebindable. If used with a non-template, non-reference, tail_const just "aliases" itself into plain old const, so it would behave sorta like logical const, except that it's actually checkable: the wrapper template can use the resulting physical const type to hold the wrapped type, thus maintaining D's physical const guarantees, while leaving other parts of the wrapper mutable so that it can implement things like reference counting, caching, etc.. Of course, this idea needs to be fleshed out more before it's actually usable, but it's something that has occurred to me multiple times, and may thus represent a pattern that could solve the logical vs. physical const dilemma in D. T -- To err is human; to forgive is not our policy. -- Samuel Adler