September 17, 2018
On Monday, September 17, 2018 5:14:28 PM MDT tide via Digitalmars-d-announce wrote:
> On Monday, 17 September 2018 at 19:10:27 UTC, Jonathan M Davis
>
> wrote:
> > Basically, @implicit is being proposed out of fear that someone, somewhere wrote a constructor that had what would be a copy constructor if D had them instead of postblit constructors and that that code would break with the DIP. Does anyone expect that such a constructor would be intended as anything other than a copy constructor (albeit one that has to be called explicitly)? And does anyone really think that such constructors are at all common, given that the correct way to handle the problem in D right now is the postblit constructor? We're talking about introducing an attribute that should be unnecessary, which will be annoying to use, and which will be error-prone given the bugs that you'll get if you forget to mark your copy constructor with it. And it's all to avoid breaking a theoretical piece of code that I would think that we could all agree is extremely rare if it exists in any real D code base at all. Simply using a transitional compiler switch like we have with other DIPs would make _way_ more sense than burdening the language with an unnecessary attribute that's just going to make it easier to write buggy code. This is clearly a case of making the language worse long term in order to avoid a theoretical problem in the short term.
> >
> > - Jonathan M Davis
>
>  From what I've read, the copy constructor can be used with
> different types:
>
> struct B
> {
> }
>
> struct A
> {
>      @implicit this(ref B b)
>      {
>      }
> }
>
>
> B foo();
>
> A a;
> a = foo(); // ok because of @implicit
> a = A(foo()); // ok without @implicit
>
> That's why it exists, otherwise I wouldn't want two types to be implicitly convertible unless i explicitly tell it to be implicit.

No. That wouldn't be a copy constructor. The DIP specifically says that "A declaration is a copy constructor declaration if it is a constructor declaration annotated with the @implicit attribute and takes only one parameter by reference that is of the same type as typeof(this)." So, it clearly must be the same type and can't be a different type.

It also says that "The copy constructor needs to be annotated with @implicit in order to distinguish a copy constructor from a normal constructor and avoid silent modification of code behavior." Andrei confirmed that that's why @implicit was there in the last major discussion on the DIP in the newsgroup. So, it's clearly there in order to avoid breaking existing code - code which is going to be _extremely_ rare.

- Jonathan M Davis



September 17, 2018
On Monday, September 17, 2018 5:07:22 PM MDT Manu via Digitalmars-d-announce wrote:
> On Mon, 17 Sep 2018 at 13:55, 12345swordy via Digitalmars-d-announce
>
> <digitalmars-d-announce@puremagic.com> wrote:
> > On Tuesday, 11 September 2018 at 15:08:33 UTC, RazvanN wrote:
> > > Hello everyone,
> > >
> > > I have finished writing the last details of the copy constructor DIP[1] and also I have published the first implementation [2]. As I wrongfully made a PR for the DIP queue in the early stages of the development of the DIP, I want to announce this way that the DIP is ready for the draft review now. Those who are familiar with the compiler, please take a look at the implementation and help me improve it!
> > >
> > > Thanks,
> > > RazvanN
> > >
> > > [1] https://github.com/dlang/DIPs/pull/129
> > > [2] https://github.com/dlang/dmd/pull/8688
> >
> > The only thing I object is adding yet another attribute to a already big bag of attributes. What's wrong with adding keywords?
> >
> > -Alexander
>
> I initially felt strongly against @implicit, it shouldn't be
> necessary, and we could migrate without it.
> But... assuming that @implicit should make an appearance anyway (it
> should! being able to mark implicit constructors will fill a massive
> usability hole in D!), then it doesn't hurt to use it eagerly here and
> avoid a breaking change at this time, since it will be the correct
> expression for the future regardless.

Except that @implicit could be introduced for other constructors without having it on copy constructors, and the fact that copy constructors will require it is just going to cause bugs, because plenty of folks are going to forget to use it and end up with the default copying behavior instead of their custom copy constructor being used. Good testing should find that pretty quickly, but it's almost certainly going to be a common bug, and it has no need to exist. It's all there in order to avoid breaking code that's likely only theoretical and not something that actual D code bases have done. And if there is a stray code base that did it, it's certainly going to be in the extreme minority, and the code will almost certainly work as a proper copy constructor anyway, since that's pretty much the only reason to write such a constructor. So, we'd be trying to avoid breaking very rare code by introducing a feature that will definitely cause bugs. IMHO, it would be _far_ better to just use a transitional -dip* compiler flag like we have with other DIPs. It would also give us the benefit of being able to bang on the implementation a bit before making it the normal behavior.

We can still add @implicit to other constructors for implicit construction with a later DIP (assuming that Walter and Andrei could be convinced of it). I don't see how having it on copy constructors really helps with that. It just means that the attribute would already be there, not that it would necessarily ever be used for what you want, and _not_ having it on copy constructors wouldn't prevent it from being used for implicit construction if such a DIP were ever accepted. So, while I understand that you want implicit construction, I think that it's a huge mistake to tie that up into copy constructors, particularly since it really doesn't make sense to have copy constructors that aren't implicit, and having @implicit for copy constructiors is going to cause bugs when it's forgotten.

- Jonathan M Davis



September 17, 2018
On Monday, 17 September 2018 at 23:14:28 UTC, tide wrote:
> From what I've read, the copy constructor can be used with different types:
>
> struct B
> {
> }
>
> struct A
> {
>     @implicit this(ref B b)
>     {
>     }
> }
>
>
> B foo();
>
> A a;
> a = foo(); // ok because of @implicit
> a = A(foo()); // ok without @implicit
>
> That's why it exists, otherwise I wouldn't want two types to be implicitly convertible unless i explicitly tell it to be implicit.

This DIP does not allow this, but apparently it is on the horizon[1],

>>>  it will be easier to extend the feature to copy construct from any type to any type
>> Is this a thing we are even considering?
> Yes.

I don't agree with it.

[1]: https://github.com/dlang/DIPs/pull/129#discussion_r218006614
September 18, 2018
On Monday, 17 September 2018 at 23:32:39 UTC, Jonathan M Davis wrote:
> On Monday, September 17, 2018 5:07:22 PM MDT Manu via Digitalmars-d-announce wrote:
>> [...]
>
> Except that @implicit could be introduced for other constructors without having it on copy constructors, and the fact that copy constructors will require it is just going to cause bugs, because plenty of folks are going to forget to use it and end up with the default copying behavior instead of their custom copy constructor being used. Good testing should find that pretty quickly, but it's almost certainly going to be a common bug, and it has no need to exist. It's all there in order to avoid breaking code that's likely only theoretical and not something that actual D code bases have done. And if there is a stray code base that did it, it's certainly going to be in the extreme minority, and the code will almost certainly work as a proper copy constructor anyway, since that's pretty much the only reason to write such a constructor. So, we'd be trying to avoid breaking very rare code by introducing a feature that will definitely cause bugs. IMHO, it would be _far_ better to just use a transitional -dip* compiler flag like we have with other DIPs. It would also give us the benefit of being able to bang on the implementation a bit before making it the normal behavior.
>
> We can still add @implicit to other constructors for implicit construction with a later DIP (assuming that Walter and Andrei could be convinced of it). I don't see how having it on copy constructors really helps with that. It just means that the attribute would already be there, not that it would necessarily ever be used for what you want, and _not_ having it on copy constructors wouldn't prevent it from being used for implicit construction if such a DIP were ever accepted. So, while I understand that you want implicit construction, I think that it's a huge mistake to tie that up into copy constructors, particularly since it really doesn't make sense to have copy constructors that aren't implicit, and having @implicit for copy constructiors is going to cause bugs when it's forgotten.
>
> - Jonathan M Davis

I think this can be made in to a compiler error.

The logic would be if there is any copy constructor defined (by copy constructor I mean a constructor that gets passed an object that can be used to construct typeof(this) - so ignore definition in DIP), then default copy construction is a compiler error unless an @implicit copy constructor is defined.

struct A {
  this(ref A) {}
}

A a;
A b = a; // error, cannot implicitly copy because an explicit one is provided
A c = A(a); // ok

This will break compilation of current code that has an explicit copy constructor, and the fix is simply to add the attribute @implicit.

September 18, 2018
On Tuesday, September 18, 2018 10:58:39 AM MDT aliak via Digitalmars-d- announce wrote:
> This will break compilation of current code that has an explicit copy constructor, and the fix is simply to add the attribute @implicit.

In that case, why not just use a transitional compiler switch? Why force everyone to mark their copy constructors with @implicit forever? The whole point of adding the attribute was to avoid breaking existing code.

- Jonathan M Davis



September 19, 2018
On Wednesday, 19 September 2018 at 00:05:15 UTC, Jonathan M Davis wrote:
> On Tuesday, September 18, 2018 10:58:39 AM MDT aliak via Digitalmars-d- announce wrote:
>> This will break compilation of current code that has an explicit copy constructor, and the fix is simply to add the attribute @implicit.
>
> In that case, why not just use a transitional compiler switch? Why force everyone to mark their copy constructors with @implicit forever? The whole point of adding the attribute was to avoid breaking existing code.
>
> - Jonathan M Davis

Apparently because extending copy constructors are intended to be extended to types other than typeof(this), which would also be implicit, and then @implicit is to make sure that you actually want this(ref SomethingElse){ ... } to be implicitly called when

A a;
B b;
...
b = a;

which I think is a bad idea, not the least of which is because thats what opAssign is for.

See https://github.com/dlang/DIPs/pull/129#discussion_r218006614
September 19, 2018
On Wednesday, 19 September 2018 at 00:05:15 UTC, Jonathan M Davis wrote:
> On Tuesday, September 18, 2018 10:58:39 AM MDT aliak via Digitalmars-d- announce wrote:
>> This will break compilation of current code that has an explicit copy constructor, and the fix is simply to add the attribute @implicit.
>
> In that case, why not just use a transitional compiler switch? Why force everyone to mark their copy constructors with @implicit forever? The whole point of adding the attribute was to avoid breaking existing code.
>
> - Jonathan M Davis

Well one breaks compilation and the other is silent code changes. And No.compilerSwitch > Yes.compilerSwitch when possible.

I'm actually not strongly for @implicit btw.
September 21, 2018
On Wednesday, 19 September 2018 at 00:05:15 UTC, Jonathan M Davis wrote:
> On Tuesday, September 18, 2018 10:58:39 AM MDT aliak via Digitalmars-d- announce wrote:
>> This will break compilation of current code that has an explicit copy constructor, and the fix is simply to add the attribute @implicit.
>
> In that case, why not just use a transitional compiler switch? Why force everyone to mark their copy constructors with @implicit forever? The whole point of adding the attribute was to avoid breaking existing code.
>
> - Jonathan M Davis

What about a command-line switch that just detects copy constructors?

LLVM 8 supposedly has a new feature which breaks compatibility for casts from float -> int:

Floating-point casts—converting a floating point number to an integer by discarding the data after the decimal—has been optimized, but in a way that might cause problems for developers who rely on undefined behavior around this feature. Clang has a new command-line switch to detect this issue.

Could we do copy-constructors in a similar way?
September 22, 2018
On Monday, 17 September 2018 at 19:10:27 UTC, Jonathan M Davis wrote:
> On Monday, September 17, 2018 8:27:16 AM MDT Meta via Digitalmars-d-announce wrote:
>> [...]
>
> Honestly, I don't think that using a pragma instead of an attribute fixes much, and it goes against the idea of what pragmas are supposed to be for in that pragmas are supposed to be compiler-specific, not really part of the language.
>
> [...]

I totally agree with this.
September 22, 2018
On Monday, 17 September 2018 at 23:07:22 UTC, Manu wrote:
> On Mon, 17 Sep 2018 at 13:55, 12345swordy via Digitalmars-d-announce <digitalmars-d-announce@puremagic.com> wrote:
>>
>> On Tuesday, 11 September 2018 at 15:08:33 UTC, RazvanN wrote:
>> > Hello everyone,
>> >
>> > I have finished writing the last details of the copy constructor DIP[1] and also I have published the first implementation [2]. As I wrongfully made a PR for the DIP queue in the early stages of the development of the DIP, I want to announce this way that the DIP is ready for the draft review now. Those who are familiar with the compiler, please take a look at the implementation and help me improve it!
>> >
>> > Thanks,
>> > RazvanN
>> >
>> > [1] https://github.com/dlang/DIPs/pull/129
>> > [2] https://github.com/dlang/dmd/pull/8688
>>
>> The only thing I object is adding yet another attribute to a already big bag of attributes. What's wrong with adding keywords?
>>
>> -Alexander
>
> I initially felt strongly against @implicit, it shouldn't be
> necessary, and we could migrate without it.
> But... assuming that @implicit should make an appearance anyway (it
> should! being able to mark implicit constructors will fill a massive
> usability hole in D!), then it doesn't hurt to use it eagerly here and
> avoid a breaking change at this time, since it will be the correct
> expression for the future regardless.

If that where the case, then why not make it an actual keyword? A frequent complaint regarding D is that there are too many attributes, this will undoubtedly adding more to it.

-Alexander