Deprecating this(this)

Jonathan M Davis newsgroup.d at jmdavisprog.com
Wed Apr 4 23:08:26 UTC 2018


On Wednesday, April 04, 2018 15:51:25 H. S. Teoh via Digitalmars-d wrote:
> On Wed, Apr 04, 2018 at 03:30:39PM -0700, Walter Bright via Digitalmars-d 
wrote:
> > On 4/1/2018 3:49 AM, bachmeier wrote:
> > > What I was wondering too. I mean, breaking changes just don't happen
> > > to this language. Now there will be, without even an indication of
> > > how existing code would have to be rewritten, or how this
> > > large-scale breakage is different than the breakages that just can't
> > > happen because reasons. I guess that's why there's always the
> > > disclaimer, "We'll only break code if there's a really good reason."
> > > That reason is "in case we want to".
> >
> > The idea is not to introduce a breaking change. Postblits will remain.
> > The copy constructor will be an additional construct, and if one is
> > defined, it will be preferred.
>
> This may lead to trouble, unless we explicitly make it illegal for
> something to have both a postblit and a copy ctor. Having the two
> interact with each other seems likely to lead to a lot of pathological,
> hard-to-understand results.

+1

> > Eventually (years later) postblits will be slowly deprecated and
> > eventually removed.
>
> Actually, if it's possible to have them coexist and there are no
> disadvantages to doing so, why not just leave both of them in?  Then
> cases where postblits give the best performance could just be left
> as-is, and cases that require a copy ctor can use a copy ctor.

The big disadvantage is that you would have to deal with two distinct ways
to copy objects and would have to explain them both to everyone learnig D.
AFAIK, the only real advantage to a postblit constructor is that you don't
have to explicitly copy everything like you do when declaring a copy
constructor in C++ - you just change the parts that need to be changed after
the copy is made in order to make it a deep copy or do whatever you need to
do to finish making the copy what it should be. As such, if we define copy
constructors in a way that only requires listing the members that are
actually going to be different from the default copy, then I really don't
see an advantage to postblit constructors.

Hmmm. And actually, thinking about that, I almost wonder if we could just
change this(this) to be a copy constructor. Assume for a moment that inside
this(this), we provide a new symbol that is the this pointer/reference for
the original. We then have make it so that any member variable in the newly
constructed object which is read before it is assigned is default-copied. As
such,

this(this)
{
}

would just default-copy everything basically as it does now. And if you
currently had

this(this)
{
    _foo = _foo.dup;
}

then after the change, it would still have the same semantics, because the
_foo is used before it is assigned, so it must be default-copied. However,
if we provide the object being copied via an invisible ref (like this)
called orig, doing

this(this)
{
    _foo = orig._foo;
}

then that would directly initialize _foo without it being default-copied. As
such, existing postblit constructors should continue to work, but it would
be straightforward to turn them into copy constructors, and most of the
changes would be underneath the hood.

I don't know if orig is the best name (and making it a keyword would be
really annoying, since it's a name that I use all the time), but on the
surface at least, the idea seems sound to me. And assuming that there isn't
a big implementation issue that makes it a serious problem, it should
actually make transitioning from postblit constructors to copy constructors
very clean and negate the need for any kind of deprecation process.

- Jonathan M Davis



More information about the Digitalmars-d mailing list