On Friday, 19 February 2016 at 21:53:16 UTC, Walter Bright wrote:
On 2/19/2016 4:38 AM, Jonathan M Davis wrote:
Yes, as long as you have the source code, finding @trusted violations is _way_ easier in D than it is in C++, but the fact that it's possible to cast away const and mutate still means that the compiler can't actually guarantee that an
object is not mutated via a const reference to it.

All languages that guarantee safety have this issue - Rust and C# have 'unsafe' blocks, and Java has the JNI C interface. Even Haskell has its Foreign Function Interface.

The idea is to encapsulate such, which D does as well as any other language. This is not a defect of D.

I don't think that we should change D in that regard. It _is_ a problem with having "unsafe" blocks, and that's life with a systems language. I was just trying to make the point that the result is that the compiler can't actually guarantee that const isn't mutated. It can just reduce how much code could violate that guarantee and guarantee that as long as the programmer did the right thing in the @trusted code (or there is no @trusted code), then the guarantee about const not mutating will hold. So, it's making guarantees but with caveats where the caveats are fairly easy to track down (at least as long as you have the source), whereas C++'s guarantees have barn-sized caveats that are _not_ easy to track down.

This does not work for opaque types.

Why not? I would expect the opaque type to have to have it too, e.g.

     @mutable struct S;

That would mean you're proposing '@mutable const' as a type constructor, which you'd earlier said otherwise.

Sorry about that. I think that I missed the "struct" in the declaration that you wrote earlier and misunderstood what you were talking about, but the idea is that @mutable would be part of the type such that you wouldn't be slapping @mutable on every declaration that uses the type - e.g.

auto foo(@mutable S bar) {...}

wouldn't make sense (which is what I mistakenly thought you were referring to). But both when you have the full definition and an opaque declaration for the type, the @mutable has to be there, e.g.

@mutable struct S
{
   ...
}

or

@mutable struct S;

Then the fact that S has @mutable members is part of the type regardless of whether you see the full definition or an opaque one, and the compiler can treat it appropriately (also, any programmer trying to verify whether a type has @mutable members or not can look at either the full definition or the opaque one and see it at a glance). AFAIK, the only place that it would end up being hidden would be references to base classes, since the derived class could be @mutable, but the base class wouldn't be (since it has no @mutable members). However, since the @mutable would be visible when the type is constructed (since it would be constructing the derived type), the compiler could see that it wouldn't be legitimate to construct it as immutable (unless we figured out how to make @mutable work with immutable, but that's a whole other layer of complication of questionable value), which might introduce problems with pure functions implicitly casting to immutable if we're not careful, but I think that that's resolvable. Certainly, it would be impossible to construct an @mutable type as immutable.

But ultimately, any code that does not use @mutable should be the same as it is now, with the full set of guarantees that it currently has. It's just the new code that uses @mutable that would have reduced guarantees (but would then still have the full guarantees for the non-@mutable members), and it would give us a backdoor that would not run afoul of immutable. It would solve the major use cases that are causing folks to cast away const and mutate, thinking that it was legit as long as the data wasn't actually immutable - including the cases that Andrei has had recently with allocators and reference counts. So, we essentially get a type safe logical const, though obviously, as with @trusted, it'll still be up to the programmer to not be stupid about what they mark as @mutable. But it'll also be easily greppable like @trusted is (and actually, as ugly as those @ symbols arguably are, they really do make grepping easier by significantly reducing the risk of false positives).

- Jonathan M Davis

Reply via email to