www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - copy constructors need documentation

reply Manu <turkeyman gmail.com> writes:
Someone needs to write up the documentation for copy constructors.
There's no source on how to write them, and explaining how to handle
all the different qualifier cases and such.
Currently, you have to troll through threads and try and interpret a
DIP to work it out... it's not good enough. A user wouldn't even know
D has copy constructors by looking at the language reference on
dlang.org.
Aug 04
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 08/04/2019 03:16 PM, Manu wrote:
 Someone needs to write up the documentation for copy constructors.
... so that I can update "Programming in D". I haven't followed the original discussions, did not understand the DConf presentation fully, do not know all interactions with postblit, etc. Help! :) Ali
Aug 04
parent Manu <turkeyman gmail.com> writes:
On Sun, Aug 4, 2019 at 6:35 PM Ali Çehreli via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 08/04/2019 03:16 PM, Manu wrote:
 Someone needs to write up the documentation for copy constructors.
... so that I can update "Programming in D". I haven't followed the original discussions, did not understand the DConf presentation fully, do not know all interactions with postblit, etc. Help! :)
Exactly! One of these days, Andrei is gonna need to update his book too...
Aug 05
prev sibling parent reply RazvanN <razvan.nitu1305 gmail.com> writes:
On Sunday, 4 August 2019 at 22:16:05 UTC, Manu wrote:
 Someone needs to write up the documentation for copy 
 constructors.
 There's no source on how to write them, and explaining how to 
 handle
 all the different qualifier cases and such.
 Currently, you have to troll through threads and try and 
 interpret a
 DIP to work it out... it's not good enough. A user wouldn't 
 even know
 D has copy constructors by looking at the language reference on
 dlang.org.
There is this documentation [1] that covers most of the aspects. I didn't write too much about qualifiers in that documentation because existing overloading and implicit conversion rules apply (as stated in the DIP). Can you point out explicitly what you think is vaguely explained? [1] https://dlang.org/spec/struct.html#struct-copy-constructor
Aug 05
parent reply Manu <turkeyman gmail.com> writes:
On Mon, Aug 5, 2019 at 12:55 AM RazvanN via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Sunday, 4 August 2019 at 22:16:05 UTC, Manu wrote:
 Someone needs to write up the documentation for copy
 constructors.
 There's no source on how to write them, and explaining how to
 handle
 all the different qualifier cases and such.
 Currently, you have to troll through threads and try and
 interpret a
 DIP to work it out... it's not good enough. A user wouldn't
 even know
 D has copy constructors by looking at the language reference on
 dlang.org.
There is this documentation [1] that covers most of the aspects. I didn't write too much about qualifiers in that documentation because existing overloading and implicit conversion rules apply (as stated in the DIP). Can you point out explicitly what you think is vaguely explained? [1] https://dlang.org/spec/struct.html#struct-copy-constructor
I'm so sorry, I completely missed that section of doco. It's actually quite comprehensive. I don't know why I didn't find it initially when I went looking. Somehow the organisation didn't get me there. It's a very tough read though, I had to jump around a lot; like, I was trying to work out why a qualified constructor works, and that's detailed in another section (which I still don't understand; how can I assign to an immutable `this`), but yeah, sorry for the false alarm!
Aug 05
parent reply RazvanN <razvan.nitu1305 gmail.com> writes:
On Monday, 5 August 2019 at 09:01:39 UTC, Manu wrote:
 On Mon, Aug 5, 2019 at 12:55 AM RazvanN via Digitalmars-d 
 <digitalmars-d puremagic.com> wrote:
 [...]
I'm so sorry, I completely missed that section of doco. It's actually quite comprehensive. I don't know why I didn't find it initially when I went looking. Somehow the organisation didn't get me there.
No worries!
 It's a very tough read though, I had to jump around a lot; 
 like, I was
 trying to work out why a qualified constructor works, and that's
 detailed in another section (which I still don't understand; 
 how can I
 assign to an immutable `this`), but yeah, sorry for the false 
 alarm!
Long story short: that's basically initialization of an immutable `struct`, therefore it is allowed. What I find weird is that you can define opAssign on `immutable` objects (wtf?!).
Aug 05
next sibling parent reply Eduard Staniloiu <edi33416 gmail.com> writes:
On Monday, 5 August 2019 at 09:07:17 UTC, RazvanN wrote:
 On Monday, 5 August 2019 at 09:01:39 UTC, Manu wrote:
 On Mon, Aug 5, 2019 at 12:55 AM RazvanN via Digitalmars-d 
 <digitalmars-d puremagic.com> wrote:
 [...]
I'm so sorry, I completely missed that section of doco. It's actually quite comprehensive. I don't know why I didn't find it initially when I went looking. Somehow the organisation didn't get me there.
No worries!
 It's a very tough read though, I had to jump around a lot; 
 like, I was
 trying to work out why a qualified constructor works, and 
 that's
 detailed in another section (which I still don't understand; 
 how can I
 assign to an immutable `this`), but yeah, sorry for the false 
 alarm!
Long story short: that's basically initialization of an immutable `struct`, therefore it is allowed. What I find weird is that you can define opAssign on `immutable` objects (wtf?!).
I believe that the reason behind it is that you can't modify an immutable instance, so defining `opAssign` for `immutable` types wouldn't be of any use. Probably the same should go for `const`. The curious case is that you can actually define the operator, but you can't call it https://run.dlang.io/is/RE0g9S I've never written a qualified `opAssign` based on the reasoning above and, imho, it holds water.
Aug 05
parent reply ag0aep6g <anonymous example.com> writes:
On 05.08.19 14:27, Eduard Staniloiu wrote:
 I believe that the reason behind it is that you can't modify an 
 immutable instance,
 so defining `opAssign` for `immutable` types wouldn't be of any use.
 
 Probably the same should go for `const`.
 
 The curious case is that you can actually define the operator, but you 
 can't call it
 https://run.dlang.io/is/RE0g9S
 
 I've never written a qualified `opAssign` based on the reasoning above 
 and, imho, it holds water.
An immutable opAssign doesn't seem particularly useful, but it's also not unsound by itself. Or is there a good reason why the following shouldn't work? ---- int x; struct S { void opAssign(S rhs) immutable { ++x; } } void main() { immutable S s; s = s; } ----
Aug 05
parent reply Olivier FAURE <couteaubleu gmail.com> writes:
On Monday, 5 August 2019 at 12:42:34 UTC, ag0aep6g wrote:
 Or is there a good reason why the following shouldn't work?
Well, it's a crime against understandable code and against reason itself, but it's not strictly *unsound* per se.
Aug 05
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, August 5, 2019 7:33:19 AM MDT Olivier FAURE via Digitalmars-d 
wrote:
 On Monday, 5 August 2019 at 12:42:34 UTC, ag0aep6g wrote:
 Or is there a good reason why the following shouldn't work?
Well, it's a crime against understandable code and against reason itself, but it's not strictly *unsound* per se.
Really, it comes down to whether it's worth special-casing it to make it illegal. The type system itself prevents a const or immutable opAssign from doing something that they shouldn't (barring casts which involve undefined behavior anyway), and realistically, no one is going to define them anyway. So, while really, they shouldn't ever be declared, the fact that they can be shouldn't actually be a problem. - Jonathan M Davis
Aug 05
prev sibling parent reply Manu <turkeyman gmail.com> writes:
On Mon, Aug 5, 2019 at 2:10 AM RazvanN via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Monday, 5 August 2019 at 09:01:39 UTC, Manu wrote:
 On Mon, Aug 5, 2019 at 12:55 AM RazvanN via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 [...]
I'm so sorry, I completely missed that section of doco. It's actually quite comprehensive. I don't know why I didn't find it initially when I went looking. Somehow the organisation didn't get me there.
No worries!
 It's a very tough read though, I had to jump around a lot;
 like, I was
 trying to work out why a qualified constructor works, and that's
 detailed in another section (which I still don't understand;
 how can I
 assign to an immutable `this`), but yeah, sorry for the false
 alarm!
Long story short: that's basically initialization of an immutable `struct`, therefore it is allowed. What I find weird is that you can define opAssign on `immutable` objects (wtf?!).
So it's mutable for the time during initialisation? `typeof(this) == T`?? not `immutable(T)`? Yeah that opAssign thing is odd... perhaps you can pin some dynamic metadata against an immutable thing via some side channel? ...perhaps it seems reasonable to do that via assignment? I have no idea ;)
Aug 05
parent reply RazvanN <razvan.nitu1305 gmail.com> writes:
On Tuesday, 6 August 2019 at 01:30:30 UTC, Manu wrote:
 On Mon, Aug 5, 2019 at 2:10 AM RazvanN via Digitalmars-d 
 <digitalmars-d puremagic.com> wrote:
 On Monday, 5 August 2019 at 09:01:39 UTC, Manu wrote:
 On Mon, Aug 5, 2019 at 12:55 AM RazvanN via Digitalmars-d 
 <digitalmars-d puremagic.com> wrote:
 [...]
I'm so sorry, I completely missed that section of doco. It's actually quite comprehensive. I don't know why I didn't find it initially when I went looking. Somehow the organisation didn't get me there.
No worries!
 It's a very tough read though, I had to jump around a lot;
 like, I was
 trying to work out why a qualified constructor works, and 
 that's
 detailed in another section (which I still don't understand;
 how can I
 assign to an immutable `this`), but yeah, sorry for the false
 alarm!
Long story short: that's basically initialization of an immutable `struct`, therefore it is allowed. What I find weird is that you can define opAssign on `immutable` objects (wtf?!).
So it's mutable for the time during initialisation? `typeof(this) == T`?? not `immutable(T)`?
No. typeof(this) is going to be immutable(T) and `this` cannot be modified as in `this = something`, but the first assignment of each of this's field is considered initialization and allowed: struct T { int a; this(int a) immutable { pragma(msg, typeof(this)); // immutable(T) this.a = a; // ok, even though this.a is immutable } } Since this makes sense for constructors, it also makes sense for copy constructors as you may initialize an immutable object from a mutable one.
 Yeah that opAssign thing is odd... perhaps you can pin some 
 dynamic
 metadata against an immutable thing via some side channel? 
 ...perhaps
 it seems reasonable to do that via assignment?
 I have no idea ;)
Aug 06
next sibling parent Manu <turkeyman gmail.com> writes:
On Tue, Aug 6, 2019 at 12:55 AM RazvanN via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Tuesday, 6 August 2019 at 01:30:30 UTC, Manu wrote:
 On Mon, Aug 5, 2019 at 2:10 AM RazvanN via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On Monday, 5 August 2019 at 09:01:39 UTC, Manu wrote:
 On Mon, Aug 5, 2019 at 12:55 AM RazvanN via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 [...]
I'm so sorry, I completely missed that section of doco. It's actually quite comprehensive. I don't know why I didn't find it initially when I went looking. Somehow the organisation didn't get me there.
No worries!
 It's a very tough read though, I had to jump around a lot;
 like, I was
 trying to work out why a qualified constructor works, and
 that's
 detailed in another section (which I still don't understand;
 how can I
 assign to an immutable `this`), but yeah, sorry for the false
 alarm!
Long story short: that's basically initialization of an immutable `struct`, therefore it is allowed. What I find weird is that you can define opAssign on `immutable` objects (wtf?!).
So it's mutable for the time during initialisation? `typeof(this) == T`?? not `immutable(T)`?
No. typeof(this) is going to be immutable(T) and `this` cannot be modified as in `this = something`, but the first assignment of each of this's field is considered initialization and allowed: struct T { int a; this(int a) immutable { pragma(msg, typeof(this)); // immutable(T) this.a = a; // ok, even though this.a is immutable } } Since this makes sense for constructors, it also makes sense for copy constructors as you may initialize an immutable object from a mutable one.
👍
Aug 06
prev sibling parent reply Olivier FAURE <couteaubleu gmail.com> writes:
On Tuesday, 6 August 2019 at 07:53:25 UTC, RazvanN wrote:
 No. typeof(this) is going to be immutable(T) and `this` cannot 
 be modified
 as in `this = something`, but the first assignment of each of 
 this's field
 is considered initialization and allowed:

 struct T
 {
     int a;
     this(int a) immutable
     {
         pragma(msg, typeof(this));    // immutable(T)
         this.a = a;                   // ok, even though this.a 
 is immutable
     }
 }
Makes sense. By the way, weird edge cases like that are why I like Rust's semantics (there's no constructor, just struct initialization and factory functions). Too bad there's no non-painful way to implement them in D at this point.
Aug 06
parent reply John Colvin <john.loughran.colvin gmail.com> writes:
On Tuesday, 6 August 2019 at 08:35:29 UTC, Olivier FAURE wrote:
 On Tuesday, 6 August 2019 at 07:53:25 UTC, RazvanN wrote:
 No. typeof(this) is going to be immutable(T) and `this` cannot 
 be modified
 as in `this = something`, but the first assignment of each of 
 this's field
 is considered initialization and allowed:

 struct T
 {
     int a;
     this(int a) immutable
     {
         pragma(msg, typeof(this));    // immutable(T)
         this.a = a;                   // ok, even though 
 this.a is immutable
     }
 }
Makes sense. By the way, weird edge cases like that are why I like Rust's semantics (there's no constructor, just struct initialization and factory functions). Too bad there's no non-painful way to implement them in D at this point.
Can you not just write trivial constructors (or no constructor, if struct literals are good enough for the case in question) and then use factory functions if you want behaviour like that?
Aug 06
parent reply Olivier FAURE <couteaubleu gmail.com> writes:
On Tuesday, 6 August 2019 at 09:42:09 UTC, John Colvin wrote:
 Can you not just write trivial constructors (or no constructor, 
 if struct literals are good enough for the case in question) 
 and then use factory functions if you want behaviour like that?
Let met try it... Oh yeah, actually you can. D even does return value copy elision and everything.
Aug 06
parent John Colvin <john.loughran.colvin gmail.com> writes:
On Tuesday, 6 August 2019 at 16:20:24 UTC, Olivier FAURE wrote:
 On Tuesday, 6 August 2019 at 09:42:09 UTC, John Colvin wrote:
 Can you not just write trivial constructors (or no 
 constructor, if struct literals are good enough for the case 
 in question) and then use factory functions if you want 
 behaviour like that?
Let met try it... Oh yeah, actually you can. D even does return value copy elision and everything.
In combination with D's "private means module-private" you can initialise immutable private members this way, so I'd say you're sorted.
Aug 06