September 24, 2018
On Monday, September 24, 2018 3:20:28 PM MDT Manu via Digitalmars-d-announce wrote:
> copy-ctor is good, @implicit is also good... we want both. Even though copy-ctor is not strictly dependent on @implicit, allowing it will satisfy that there's not a breaking change, it it will also self-justify expansion of @implicit as intended without a separate and time-consuming fight, which is actually the true value of this DIP!

@implicit on copy constructors is outright bad. It would just be a source of bugs. Every time that someone forgets to use it (which plenty of programmers will forget, just like they forget to use @safe, pure, nothrow, etc.), they're going to have a bug in their program. However, unlike, with attributes like @safe or pure, they're not going to get a compiler error in their program; they're going to get a logic error. They may or may not find that bug quickly, but the compiler isn't going to point it out to them. And if @implicit weren't a thing, then the problem wouldn't even exist. @implicit is trying to get around breaking an extremely unlikely piece of code which would be far better fixed by using a transitional compiler flag and which adds _no_ value for copy constructors in the long run.

Even if we do later add @implicit to the language for regular constructors, it has no business on copy constructors. And its value on other constructors needs to be evaluated and examined on its own separately from the issue of copy constructors. We should not be letting @implicit be put onto copy constructors just to get it into the language. If it's such a valuable feature on regular constructors, it should be able to get in on a separate DIP specifically for that purpose without piggybacking in on the copy constructor DIP - especially when it's clearly going to be a source of bugs if it's required to be on copy constructors. And it just needlessly adds to the attribute soup. At least if it were added for regular constructors, it would be adding value. For copy constructors, it's just adding annoyance and the risk of bugs.

- Jonathan M Davis



September 25, 2018
On Monday, 24 September 2018 at 23:22:13 UTC, Jonathan M Davis wrote:
> @implicit on copy constructors is outright bad. It would just be a source of bugs. Every time that someone forgets to use it (which plenty of programmers will forget, just like they forget to use @safe, pure, nothrow, etc.), they're going to have a bug in their program. However, unlike, with attributes like @safe or pure, they're not going to get a compiler error in their program; they're going to get a logic error. They may or may not find that bug quickly, but the compiler isn't going to point it out to them.

I think this is the most important reason. In C++, where everything is implicit by default (which is bad) and (I think) you are encouraged to use explicit where possible, you should never use it for the copy constructor because the compiler always calls it implicitly for you and is the whole point of having:

Foo a; Foo b = a;

do something useful. Putting explicit on the copy ctor means that no longer works, one can then only use it with

Foo a; Foo b(a);

Having `Foo a; Foo b = a;` do something completely different by the addition or removal of one attribute is a serious problem just waiting to happen.


September 24, 2018
On Monday, September 24, 2018 7:59:36 PM MDT Nicholas Wilson via Digitalmars-d-announce wrote:
> On Monday, 24 September 2018 at 23:22:13 UTC, Jonathan M Davis
>
> wrote:
> > @implicit on copy constructors is outright bad. It would just be a source of bugs. Every time that someone forgets to use it (which plenty of programmers will forget, just like they forget to use @safe, pure, nothrow, etc.), they're going to have a bug in their program. However, unlike, with attributes like @safe or pure, they're not going to get a compiler error in their program; they're going to get a logic error. They may or may not find that bug quickly, but the compiler isn't going to point it out to them.
>
> I think this is the most important reason. In C++, where everything is implicit by default (which is bad) and (I think) you are encouraged to use explicit where possible, you should never use it for the copy constructor because the compiler always calls it implicitly for you and is the whole point of having:
>
> Foo a; Foo b = a;
>
> do something useful. Putting explicit on the copy ctor means that no longer works, one can then only use it with
>
> Foo a; Foo b(a);
>
> Having `Foo a; Foo b = a;` do something completely different by the addition or removal of one attribute is a serious problem just waiting to happen.

The key thing with explicit in C++ is to avoid issues with implicit conversions between types. You can get weird junk like where

int foo(string s);

foo(42);

compiles, because you have a type A with an implicit constructor which takes int, and an implicit conversion to string. Even though A isn't explicitly used here anywhere, because it's available, and no more than three conversions are required to go from int to string when using A, the compiler will use A to from int to string. That probably isn't what the programmer wanted, but the compiler will happily do it.

Because of this, it's best practice in C++ to put explicit on any constructors which take other types where you don't explicitly want the implicit conversion in order to try to avoid this conversion mess. You then only leave explicit off of constructors where you want the implicit conversion or constructors where it's unnecessary (e.g. default constructors or copy constructors). D avoids this mess by simply not having any kind of implicit construction. It just has implicit conversion via alias this. It may or may not be worth adding implicit construction via something like @implicit, but it would at least then only be on constructors which were explicitly marked with @implicit, whereas with C++, you have to use explicit to turn off the behavior. So, in C++, it's a total mess by default, whereas in D, we'd only have it where the programmer asked for it. And presumably, any DIP that added it wouldn't have the compiler do more than one conversion at a time, whereas as I understand it, C++ allows the compiler to do up to three conversions in order to make a piece of code work. But ultimately, such details will have to be decided with such a DIP.

Either way, none of this has anything to do with copy constructors. It makes no sense to have copy constructors that require that you call them explicitly. And while it would be bad enough if the DIP required that you mark copy constructors with @implicit for them to work as copy constructors and then didn't have implicit copying without @implicit, that's not what it does. Instead, what it does when you forget @implicit is revert to the default copy semantics, meaning that you have a copy constructor that needs to be called explicitly, but you didn't realize that it needed to be called explicitly, and you're blindly using the default copy semantics rather than the copy constructor. So, the semantics that the DIP describes are just plain a recipe for bugs. But since the PR has been updated to remove @implicit, maybe the DIP will be updated to remove it as well, and the whole @implicit discussion can be left to a future DIP on implicit construction and left out of copy construction entirely.

- Jonathan M Davis



September 24, 2018
On Mon, 24 Sep 2018 at 16:22, Jonathan M Davis via Digitalmars-d-announce <digitalmars-d-announce@puremagic.com> wrote:
>
> On Monday, September 24, 2018 3:20:28 PM MDT Manu via Digitalmars-d-announce wrote:
> > copy-ctor is good, @implicit is also good... we want both. Even though copy-ctor is not strictly dependent on @implicit, allowing it will satisfy that there's not a breaking change, it it will also self-justify expansion of @implicit as intended without a separate and time-consuming fight, which is actually the true value of this DIP!
>
> @implicit on copy constructors is outright bad. It would just be a source of bugs. Every time that someone forgets to use it (which plenty of programmers will forget, just like they forget to use @safe, pure, nothrow, etc.), they're going to have a bug in their program.

perhaps a rule where declaring a copy-ctor WITHOUT @explicit emits a compile error...?
September 24, 2018
On Monday, September 24, 2018 9:33:19 PM MDT Manu via Digitalmars-d-announce wrote:
> On Mon, 24 Sep 2018 at 16:22, Jonathan M Davis via
>
> Digitalmars-d-announce <digitalmars-d-announce@puremagic.com> wrote:
> > On Monday, September 24, 2018 3:20:28 PM MDT Manu via
> > Digitalmars-d-announce>
> > wrote:
> > > copy-ctor is good, @implicit is also good... we want both. Even though copy-ctor is not strictly dependent on @implicit, allowing it will satisfy that there's not a breaking change, it it will also self-justify expansion of @implicit as intended without a separate and time-consuming fight, which is actually the true value of this DIP!
> >
> > @implicit on copy constructors is outright bad. It would just be a source of bugs. Every time that someone forgets to use it (which plenty of programmers will forget, just like they forget to use @safe, pure, nothrow, etc.), they're going to have a bug in their program.
>
> perhaps a rule where declaring a copy-ctor WITHOUT @explicit emits a compile error...?

That would pretty much defeat the whole purpose of why @implicit was added to the DIP in the first place. It's just that it would turn the feared silent code breakage into a compiler error. So, I suppose that it would be an improvement, but it's the sort of thing that would have to go behind a transitional compiler switch, and as soon as we do that, why have @implicit on copy constructors at all? It makes far more sense to use a transitional compiler switch to simply sort out the problem with the potential (but highly unlikely) silent breakage and not do anything with @implicit with copy constructors whatsoever. It avoids having to put a useless attribute on copy constructors forever, and it avoids any potential bugs.

Then we can have a separate DIP that deals with @implicit and non-copy constructors for implicit construction. And maybe we do ultimately end up with @implicit on constructors in D. But if @implicit ends up on copy constructors, at best, it's going to be a language wort, since it adds zero value there, but as the DIP currently stands, it's going to be a source of bugs.

- Jonathan M Davis



September 25, 2018
After discussing with Walter and Andrei we have decided that we are going to drop @implicit for now as it may cause bugs (as Jonathan has highlighted) and consider constructors that have the form this(ref $q1 S rhs) $q2 as copy constructors. I will update the DIP with more information.

Also, regarding the cohabitation between postblit and copy constructor: in order to make the transition smoother, whenever a postblit and a copy constructor are found togheter in a struct, the former is used and the latter is ignored (even if it is a field postblit). Once the postblit is going to be deprecated we can do the opposite and use the copy constructor and ignore the postblit.

If @implicit is going to be introduced then that is going to be a DIP on its own.
September 25, 2018
On Tuesday, September 25, 2018 6:33:30 AM MDT RazvanN via Digitalmars-d- announce wrote:
> After discussing with Walter and Andrei we have decided that we are going to drop @implicit for now as it may cause bugs (as Jonathan has highlighted) and consider constructors that have the form this(ref $q1 S rhs) $q2 as copy constructors. I will update the DIP with more information.
>
> Also, regarding the cohabitation between postblit and copy constructor: in order to make the transition smoother, whenever a postblit and a copy constructor are found togheter in a struct, the former is used and the latter is ignored (even if it is a field postblit). Once the postblit is going to be deprecated we can do the opposite and use the copy constructor and ignore the postblit.
>
> If @implicit is going to be introduced then that is going to be a DIP on its own.

Yay! Thank you.

- Jonathan M Davis



September 25, 2018
On Tuesday, 25 September 2018 at 12:33:30 UTC, RazvanN wrote:
> After discussing with Walter and Andrei we have decided that we are going to drop @implicit for now as it may cause bugs (as Jonathan has highlighted) and consider constructors that have the form this(ref $q1 S rhs) $q2 as copy constructors. I will update the DIP with more information.
>
> Also, regarding the cohabitation between postblit and copy constructor: in order to make the transition smoother, whenever a postblit and a copy constructor are found togheter in a struct, the former is used and the latter is ignored (even if it is a field postblit). Once the postblit is going to be deprecated we can do the opposite and use the copy constructor and ignore the postblit.
>
> If @implicit is going to be introduced then that is going to be a DIP on its own.

Thanks!

I still think a -dip10xx flag to control which to prefer is worth doing, since

a) it won't be hard to do and will make the transition smoother still , and

b) IIRC the motivating factor for this is memory safety. Delaying memory safety while waiting for a deprecation period to expire ( O(years) ) for code that wants to remain backwards compatible with older compiler versions is not something we should be encouraging.

In the deprecation period if no flag is given prefer postblit to copy if both are defined, if flag is given prefer copy over postblit.

Nic
October 02, 2018
Hi all,

I just pushed another version of the DIP in which the major modifications among otthers are removing implicit and use copy constructor calls in all situations where a copy is made. For more details, please visit [1] and if you have the time, please offer some feedback,

Thank you,
RazvanN

[1] https://github.com/dlang/DIPs/pull/129/


October 08, 2018
On Tuesday, 2 October 2018 at 09:26:34 UTC, RazvanN wrote:
> Hi all,
>
> I just pushed another version of the DIP in which the major modifications among otthers are removing implicit and use copy constructor calls in all situations where a copy is made. For more details, please visit [1] and if you have the time, please offer some feedback,
>
> Thank you,
> RazvanN
>
> [1] https://github.com/dlang/DIPs/pull/129/

I've made all the changes in the code that the DIP includes[1] and the tests seem to be all green. I still need to add more tests; if you have any tests that you want to make sure the implementation takes into account please post them.

Cheers,
RazvanN

[1] https://github.com/dlang/dmd/pull/8688