On Monday, 15 February 2016 at 22:48:16 UTC, Walter Bright wrote:
rears its head again :-)

Head Const is what C++ has for const, i.e. it is not transitive, applies to one level only. D has transitive const.

What head const will do for us:

1. make it easy to interface to C++ code that uses const, as currently it is not very practical to do so, you have to resort to pragma(mangle)

2. supports single assignment style of programming, even if the data is otherwise mutable

The downside is, of course, language complexity.

Straight up head-const is utterly useless IMHO. That's what Java has. C++ has something far more complicated where any individual piece (or pieces) of a pointer type can be declared const without necessarily making the whole thing const. So, _that_ is what we'd need to interact with C++, and it's a downright ugly feature IMHO. Tail-const has some value, because it allows you to refer to a const object with a mutable pointer or reference, whereas head-const just makes things ugly. So, if it weren't for interacting with C++, I would give a resounding "no" to this. It's not even vaguely worth the complexity.

As for interoperability with C++, I don't know. Previously, you stated that we weren't going to do things like support interacting with C++ templates (aside from specific instantiations which weren't typed as templates), because it would mean putting a C++ compiler into D, which you didn't want to do. But increasingly, it seems like you're heading in the direction of doing that in an attempt to be able to have fantastic C++ interoperability. On the one on hand, that seems great, since being able to have your C++ code work with your D code is great, but on the other, it seems like it's going to make it so that D is contaminated by a lot of extra C++ muck just to be able to interoperate. At some point, we either need to decide that we're just not going to interoperate with C++ in some manner and lose out on some capability, or we're going to need to fully interoperate with C++ and pretty much put a C++ compiler in the D compiler, and I'd prefer that we didn't go that far.

In this particular case, doesn't this really just come down to mangling? It's undefined behavior in D to mutate a const object (even if it was constructed as mutable), so we can't just slap D const on C++ types and have that work, since the C++ code could legally mutate the object. But since C++ considers it defined behavior to mutate a const object by casting away const (or at least it does in all but some very specific cases), can we just get away with the D code treating D const as mutable? If so, then it's purely a matter of mangling. And for that, we could do something like add @cppconst or cppconst that the compiler recognizes and which is only valid in extern(C++) declarations. It would unfortunately have to be more than a simple attribute, because it would have to apply to parts of a parameter's type like C++'s const does (instead of the whole type at once), but if it were implemented such that it was just something that went on the extern(C++) function parameter types (or return types) for mangling purposes, and the D code just treated it as mutable, then it would at least restrict the muck to extern(C++).

Now, that does have the downside that the D code has no protection against mutating a C++ object that the C++ code marks as const (whereas while the C++ code can mutate, you at least have to cast away const or use the mutable keyword first), but that seems a whale of a lot better to me than trying to add non-transitive const to D.

- Jonathan M Davis

Reply via email to