digitalmars.D - Copy Constructor DIP
- RazvanN (8/8) Jul 10 2018 Hi everyone!
- Guillaume Piolat (3/11) Jul 10 2018 Does it allow to remove the "T.init must always be valid for
- Jonathan M Davis (9/23) Jul 10 2018 Why would it? init is the state of the object before any constructor run...
- Guillaume Piolat (11/22) Jul 10 2018 None, I was just reacting to
- Jonathan M Davis (29/54) Jul 10 2018 It's not necessarily expected that all of the functions on T.init are go...
- FeepingCreature (8/15) Jul 10 2018 moveEmplace bypasses opAssign, since it memcopies directly.
- Uknown (3/10) Jul 10 2018 This is where I feel being able to redefine T.init would be
- Andrei Alexandrescu (2/16) Jul 10 2018 That's not part of this proposal's charter.
- rikki cattermole (5/5) Jul 10 2018 I'm not keen on the added attribute.
- Manu (19/27) Jul 10 2018 I feel there's some things missing.
- RazvanN (37/77) Jul 11 2018 It is a simple way of defining a copy constructor without the
- Manu (13/93) Jul 11 2018 What's wrong with:
- RazvanN (22/36) Jul 11 2018 That is actually a valid constructor, according to today's
- Andrei Alexandrescu (2/23) Jul 12 2018 We will not add syntax if we can help it.
- Johannes Pfau (11/22) Jul 12 2018 We have this(this) for postblits so how about this(ref this a) for copy
- Johannes Pfau (7/31) Jul 12 2018 I just read your other replies Andrei. I guess if we're ever going use
- Atila Neves (5/15) Jul 12 2018 Because, like in C++, now you have to implement both and make
- Andrei Alexandrescu (5/20) Jul 12 2018 There's no meaningful way to avoid that. The two operations are
- Manu (10/30) Jul 12 2018 As I've said elsewhere, opAssign() can be fabricated by:
- Andrei Alexandrescu (9/43) Jul 12 2018 Not if the object has immutable fields, is immutable itself, is assigned...
- Manu (41/78) Jul 12 2018 Exactly. Is that a problem?
- Andrei Alexandrescu (2/14) Jul 12 2018 Not the charter of the current DIP.
- Manu (10/24) Jul 12 2018 In a post-blit world, with no opAssign specified, postblit will call
- Andrei Alexandrescu (3/31) Jul 12 2018 Affirmative. The DIP needs to specify how assignment is handled if no
- RazvanN (50/65) Jul 13 2018 Indeed, but this was the source of the problem also, because you
- meppl (3/24) Jul 13 2018 it can be something else. For example a lifo list pusher. Even if
- Andrei Alexandrescu (3/15) Jul 12 2018 Shouldn't hurt to add 1-2 sentences to the effect. (Also an example.)
- Andrei Alexandrescu (5/29) Jul 12 2018 Razvan: I think it would help to explain that the attribute is necessary...
- ag0aep6g (13/18) Jul 12 2018 You're still potentially changing the semantics of existing code.
- Andrei Alexandrescu (3/24) Jul 12 2018 That is correct and a liability of the current DIP. That should be
- Jacob Carlborg (9/25) Jul 14 2018 That's easily fixed by implementing a compiler recognized UDA.
- Andrei Alexandrescu (2/26) Jul 16 2018 Affirmative. We're going that route, similar to "@safe" and "@nogc".
- ag0aep6g (4/11) Jul 16 2018 @safe and @nogc are not compiler recognized UDAs. If you implement
- Andrei Alexandrescu (3/15) Jul 16 2018 Then "negative" :o). In brief @implicit follows the same implementation
- Jacob Carlborg (8/10) Jul 17 2018 Why? This is a breaking change. Why not go with an approach that
- Jonathan M Davis (15/22) Jul 10 2018 S b = a;
- Manu (13/35) Jul 10 2018 I know this, but it's not syntactically obvious, it just depends on
- RazvanN (5/9) Jul 11 2018 The @implicit is there to point out that you cannot call that
- Atila Neves (8/17) Jul 11 2018 How is this different from other types of constructors or
- Andrei Alexandrescu (6/21) Jul 12 2018 C++ is at the other end of the spectrum - constructors are too implicit,...
- Jonathan M Davis (14/22) Jul 12 2018 That's only an issue in C++, because C++ uses constructors for implicit
- Andrei Alexandrescu (10/29) Jul 12 2018 The DIP is proposing what's in the DIP :o). We actually clarify this in
- Manu (5/18) Jul 12 2018 You mean like ~this(), and op[Anything](), and front() and popFront()
- Andrei Alexandrescu (4/25) Jul 12 2018 I mentioned this, and patiently will mention it again: we need to
- Manu (34/59) Jul 12 2018 Take this reply while assuming a no-@implicit world, which I think is
- Atila Neves (6/20) Jul 13 2018 https://github.com/search?q=%22this%5C%28ref%22+language%3AD&type=Code
- Andrei Alexandrescu (21/39) Jul 13 2018 A proposal that just works without any user intervention would
- Atila Neves (8/37) Jul 13 2018 I agree on the levels of hell. I wasn't aware the kind of change
- Andrei Alexandrescu (8/47) Jul 13 2018 Great. Razvan, can you please add this example with discussion to the
- 12345swordy (4/15) Jul 13 2018 Why "@implicit" is an attribute and not a keyword?
- Atila Neves (14/65) Jul 13 2018 I came to D via C++ as well. Maybe my brain short-circuited
- Manu (8/12) Jul 13 2018 You don't find 'implicit' satisfactory as an obvious and intuitive
- =?UTF-8?B?THXDrXM=?= Marques (2/4) Jul 13 2018 Exactly.
- aliak (2/22) Jul 17 2018 https://www.google.no/search?q=allintext%3A+%22this%28ref%22+site%3Agith...
- Manu (9/34) Jul 17 2018 I clicked through quite a few. Every function that's a valid copy
- Andrei Alexandrescu (4/34) Jul 13 2018 Noted. So in summary you would be okay with changing semantics of
- Manu (17/51) Jul 13 2018 Yes, I think this is too important and fundamental to lug historical
- Manu (12/33) Jul 12 2018 Ohhh yeah, this. I finally understand your reasoning here!
- vit (3/12) Jul 11 2018 Can be explicit constructor overloaded with implicit constructor
- Manu (4/17) Jul 11 2018 If they've got the same signature, they should do the same thing...
- Andrei Alexandrescu (2/14) Jul 12 2018 Thanks for this. Yes we need to add a mention.
- Manu (5/14) Jul 11 2018 That's my point; so this is a compile error then:
- RazvanN (35/39) Jul 12 2018 Consider this code:
- Andrei Alexandrescu (10/53) Jul 12 2018 The DIP is not a tutorial on existing related parts of the language.
- Manu (20/66) Jul 12 2018 Okay. Well, I guess that I just wanted some clarity on exactly what
- Nick Treleaven (12/13) Jul 11 2018 Thanks for making the DIP. I can't get this code to compile (my
- Andrei Alexandrescu (3/23) Jul 12 2018 Odd. Timon, what would be the reason for that error? Razvan, can you
- Timon Gehr (30/43) Jul 12 2018 The reason for this specific error is that `src.i` is neither a symbol
- Timon Gehr (5/16) Jul 12 2018 The error messages are actually:
- Andrei Alexandrescu (2/51) Jul 12 2018 Thanks!
- =?UTF-8?B?THXDrXM=?= Marques (19/23) Jul 12 2018 When designing D libraries than lean towards DSL style, I've
- =?UTF-8?B?THXDrXM=?= Marques (13/31) Jul 12 2018 More details. The DIP says:
- =?UTF-8?B?THXDrXM=?= Marques (7/19) Jul 12 2018 BTW: Multiple alias this is still planned for inclusion in D,
- =?UTF-8?B?THXDrXM=?= Marques (7/14) Jul 12 2018 Sorry for the stream-of-conscience type posts. But, to clarify
- Andrei Alexandrescu (2/15) Jul 12 2018 The DIP mentions the interaction of @implicit with alias this.
- =?UTF-8?B?THXDrXM=?= Marques (4/5) Jul 12 2018 Not the interaction I was asking about, although admittedly it
- Andrei Alexandrescu (3/23) Jul 12 2018 Again: not the charter of this DIP, so you should ask yourself, not us,
- =?UTF-8?B?THXDrXM=?= Marques (10/12) Jul 12 2018 Look, I understand it can be frustrating to have a concrete
- jmh530 (6/18) Jul 12 2018 I like the idea of implicit conversions (until I've been
- Andrei Alexandrescu (4/17) Jul 12 2018 Definitely good topics to discuss. This is a collaborative process, not
- Manu (9/30) Jul 12 2018 @implicit constructors state what types an object may *accept*.
- Andrei Alexandrescu (7/36) Jul 12 2018 No, only constructors annotated with @implicit would be implicit. But
- Manu (4/40) Jul 12 2018 I feel like this DIP depends on an @implicit DIP, and that one needs
- Andrei Alexandrescu (2/46) Jul 12 2018 Negative.
- Manu (24/72) Jul 12 2018 n
- Meta (13/19) Jul 12 2018 Nothing is being slipped by as far as I'm concerned. @implicit is
- Manu (24/38) Jul 12 2018 That's the whole point though.
- Andrei Alexandrescu (22/49) Jul 13 2018 A couple of simple ideas are making the process productive. One is to
- Manu (49/76) Jul 13 2018 What "I don't like" is using an attribute as a marker, and especially
- rikki cattermole (4/9) Jul 13 2018 You are very much not alone.
- Meta (4/17) Jul 13 2018 I'm not crazy about it either, but it may be a necessary evil to
- Andrei Alexandrescu (20/32) Jul 13 2018 It's a very simple process - @implicit is not invented as much as a give...
- Andrei Alexandrescu (15/17) Jul 13 2018 The specification of @implicit is in the DIP in full: a constructor that...
- Manu (23/30) Jul 13 2018 Right, and this is 100% of my concern here.
- rikki cattermole (4/5) Jul 14 2018 Given how many of us are objecting to the syntax, I'm going to place
- Manu (5/10) Jul 14 2018 I just want to reiterate again, I'm not seeking alternative syntax, I ju...
- =?UTF-8?B?THXDrXM=?= Marques (23/28) Jul 14 2018 That is the problem: you are using a very generic name
- Andrei Alexandrescu (20/23) Jul 14 2018 I'm totally cool with giving the attribute a more obscure name such as
- Johan Engelen (10/14) Jul 14 2018 Strongly agree with this.
- rikki cattermole (15/30) Jul 14 2018 Really any mention of the "future" in a DIP section wise, should be
- docandrew (9/34) Jul 16 2018 I think in this case, a more obscure name like @copyctor is more
- Manu (3/42) Jul 16 2018 But that's the point, and the key advantage of the name ;)
- Andrei Alexandrescu (2/3) Jul 17 2018 [:nod:]
- aliak00 (15/60) Jul 17 2018 Aye! And in this case it really is implicit copy construction.
- Andrei Alexandrescu (4/6) Jul 17 2018 On the contrary, it is redundant and uninformative. It applies to
- =?UTF-8?B?THXDrXM=?= Marques (8/25) Jul 17 2018 I also think a more general attribute is better. I think there's
- Manu (7/15) Jul 12 2018 I'd like to see a mention on extern(C++) copy constructors; are they
- xenon325 (10/13) Jul 13 2018 Regarding "exactly in this order". The code below would be
- Andrei Alexandrescu (2/19) Jul 13 2018 We'll change that part to accept the standard attribute syntax.
Hi everyone! I managed to put together a first draft of the DIP for adding the copy constructor to the language [1]. If anyone is interested, please take a look. Suggestions and comments about technical aspects and wording are all welcome. Thanks, RazvanN [1] https://github.com/dlang/DIPs/pull/129
Jul 10 2018
On Tuesday, 10 July 2018 at 10:47:04 UTC, RazvanN wrote:Hi everyone! I managed to put together a first draft of the DIP for adding the copy constructor to the language [1]. If anyone is interested, please take a look. Suggestions and comments about technical aspects and wording are all welcome. Thanks, RazvanN [1] https://github.com/dlang/DIPs/pull/129Does it allow to remove the "T.init must always be valid for structs" rule?
Jul 10 2018
On Tuesday, 10 July 2018 04:52:18 MDT Guillaume Piolat via Digitalmars-d wrote:On Tuesday, 10 July 2018 at 10:47:04 UTC, RazvanN wrote:Why would it? init is the state of the object before any constructor runs, and quite a few things rely on it. The fact that we've allowed default initialization to be disabled already causes plenty of problems as it is. It's occasionally useful, but it definitely complicates things. D was designed with the idea that every type has an init value. What problem are you trying to solve here? - Jonathan M DavisHi everyone! I managed to put together a first draft of the DIP for adding the copy constructor to the language [1]. If anyone is interested, please take a look. Suggestions and comments about technical aspects and wording are all welcome. Thanks, RazvanN [1] https://github.com/dlang/DIPs/pull/129Does it allow to remove the "T.init must always be valid for structs" rule?
Jul 10 2018
On Tuesday, 10 July 2018 at 11:58:53 UTC, Jonathan M Davis wrote:None, I was just reacting to https://medium.com/ feepingcreature/d-structs-dont-work-for-domain-data-c09332349f43 Proper D structs almost require having a T.init that is valid, and in turn many public members may get to check for internal validity before doing things. This is in stark contrast to C++ where "proper" constructor is guaranteed so you don't check such validity. What is a "correct" T.init for a mutex RAII struct? It is a null handle value. It's obviously an invalid value for any purpose, but the D wrapper has to be a valid struct.Does it allow to remove the "T.init must always be valid for structs" rule?Why would it? init is the state of the object before any constructor runs, and quite a few things rely on it. The fact that we've allowed default initialization to be disabled already causes plenty of problems as it is. It's occasionally useful, but it definitely complicates things. D was designed with the idea that every type has an init value. What problem are you trying to solve here? - Jonathan M Davis
Jul 10 2018
On Tuesday, 10 July 2018 06:34:34 MDT Guillaume Piolat via Digitalmars-d wrote:On Tuesday, 10 July 2018 at 11:58:53 UTC, Jonathan M Davis wrote:It's not necessarily expected that all of the functions on T.init are going to work. It's the stuff like copying it, assigning it, destroying it, etc. that have to work (and aside from destruction, you can even disable them if you need to). Not even toString actually needs to work. It's just that it's so common for folks to print values that it gets annoying when it doesn't work. And yes, if T.init does not match the invariant, then you can start running into problems, though it isn't necessarily fatal. Basically, in that case, you're forced to disable default initialization and avoid actually doing much with the init value. Honestly though, the reason that I think that invariants are terrible has nothing to do with T.init specifically but with opAssign. The invariant gets checked before opAssign, and in many cases, this makes sense, but in the case where you're doing something like void initialization or using emplace on uninitialized memory, it blows up in your face if the garbage that happened to be in the struct didn't match the invariant. The same would happen if T.init does not pass the invariant, but T.init isn't required to hit the problem. It's the fact that you can't bypass the invariant when giving the object a new value that's the main problem. If both assignment and copying worked without checking the invariant, then invariants would be a _lot_ more useful. Unfortunately, when I argued about this quite a bit with regards to opAssign several years ago, Walter didn't agree at all. He thought that it was critical that the invariant be valid when opAssign was called - and there are cases where that's arguably true - but since it doesn't work once you try to do fancier stuff like emplace, I'm of the opinion that invariants are unfortunately a waste of time - even without getting into the issue of init values. - Jonathan M DavisNone, I was just reacting to https://medium.com/ feepingcreature/d-structs-dont-work-for-domain-data-c0 9332349f43 Proper D structs almost require having a T.init that is valid, and in turn many public members may get to check for internal validity before doing things. This is in stark contrast to C++ where "proper" constructor is guaranteed so you don't check such validity. What is a "correct" T.init for a mutex RAII struct? It is a null handle value. It's obviously an invalid value for any purpose, but the D wrapper has to be a valid struct.Does it allow to remove the "T.init must always be valid for structs" rule?Why would it? init is the state of the object before any constructor runs, and quite a few things rely on it. The fact that we've allowed default initialization to be disabled already causes plenty of problems as it is. It's occasionally useful, but it definitely complicates things. D was designed with the idea that every type has an init value. What problem are you trying to solve here? - Jonathan M Davis
Jul 10 2018
On Tuesday, 10 July 2018 at 13:38:33 UTC, Jonathan M Davis wrote:He thought that it was critical that the invariant be valid when opAssign was called - and there are cases where that's arguably true - but since it doesn't work once you try to do fancier stuff like emplace, I'm of the opinion that invariants are unfortunately a waste of time - even without getting into the issue of init values. - Jonathan M DavismoveEmplace bypasses opAssign, since it memcopies directly. However, it resets its source value to T.init... so if T.init isn't valid, you simply crash whenever the source value goes out of scope. Using types with an invalid T.init feels like playing musical chairs with a crash. You can shuffle things around, and make some parts work, but *something* is always left crashing at the end.
Jul 10 2018
On Tuesday, 10 July 2018 at 14:28:09 UTC, FeepingCreature wrote:On Tuesday, 10 July 2018 at 13:38:33 UTC, Jonathan M Davis wrote:This is where I feel being able to redefine T.init would be useful, but as Andrei said, that is beyond the scope of this DIP[...]Using types with an invalid T.init feels like playing musical chairs with a crash. You can shuffle things around, and make some parts work, but *something* is always left crashing at the end.
Jul 10 2018
On 07/10/2018 06:52 AM, Guillaume Piolat wrote:On Tuesday, 10 July 2018 at 10:47:04 UTC, RazvanN wrote:That's not part of this proposal's charter.Hi everyone! I managed to put together a first draft of the DIP for adding the copy constructor to the language [1]. If anyone is interested, please take a look. Suggestions and comments about technical aspects and wording are all welcome. Thanks, RazvanN [1] https://github.com/dlang/DIPs/pull/129Does it allow to remove the "T.init must always be valid for structs" rule?
Jul 10 2018
I'm not keen on the added attribute. Something along the lines of: this(this; ref Foo foo) {} might look a little better no? And now no super special attribute to worry about parsing.
Jul 10 2018
On Tue, 10 Jul 2018 at 03:50, RazvanN via Digitalmars-d <digitalmars-d puremagic.com> wrote:Hi everyone! I managed to put together a first draft of the DIP for adding the copy constructor to the language [1]. If anyone is interested, please take a look. Suggestions and comments about technical aspects and wording are all welcome. Thanks, RazvanN [1] https://github.com/dlang/DIPs/pull/129I feel there's some things missing. 1. Explain the need and reasoning behind ` implicit`... that's weird and I don't like it at face value. 2. It looks like copy constructors are used to perform assignments (and not constructions)... but, there is also opAssign. What gives? Eg: S b = a; // <- copy construction? looks like an assignment. And not: S b = S(a); // <- actually looks like a construction, but this syntax seems to not be intended (and rightly so, it's pretty terrible) 3. In C++, copy constructors and copy assignment operators come in pairs (which is totally lame!), but we don't see that same pattern extend here, and it's not clear at all why. 4. Given the special rules where assignments are lifted to constructions, I want to know when that occurs (maybe that is already spec-ed wrt postblit?) - Manu
Jul 10 2018
On Tuesday, 10 July 2018 at 20:58:09 UTC, Manu wrote:On Tue, 10 Jul 2018 at 03:50, RazvanN via Digitalmars-d <digitalmars-d puremagic.com> wrote:It is a simple way of defining a copy constructor without the need of adding new keywords and with minimal additions to the parser.Hi everyone! I managed to put together a first draft of the DIP for adding the copy constructor to the language [1]. If anyone is interested, please take a look. Suggestions and comments about technical aspects and wording are all welcome. Thanks, RazvanN [1] https://github.com/dlang/DIPs/pull/129I feel there's some things missing. 1. Explain the need and reasoning behind ` implicit`... that's weirdand I don't like it at face value. 2. It looks like copy constructors are used to perform assignments (and not constructions)... but, there is also opAssign. What gives? Eg: S b = a; // <- copy construction? looks like an assignment. And not: S b = S(a); // <- actually looks like a construction, but this syntax seems to not be intended (and rightly so, it's pretty terrible) 3. In C++, copy constructors and copy assignment operators come in pairs (which is totally lame!), but we don't see that same pattern extend here, and it's not clear at all why. 4. Given the special rules where assignments are lifted to constructions, I want to know when that occurs (maybe that is already spec-ed wrt postblit?) - ManuCopy construction is used solely when the object was not initialized and it cannot be used otherwise. Consider this example: struct A { immutable int a = 7; implicit this(ref A another) { this.a = A.a; // first assignment over .init state - ok } void opAssign(A rhs) { this.a = rhs.a; } } void main() { A a = A(2); A b = a; // initialization -> calls copy constructor b = a; // cannot call copy constructor because it will // modify immutable; call opAssign. } The first assignment of b calls the copy constructor and the immutable field is initialized; later assignments to b.a will result in "modify immutable" error. The second assignment of b cannot call the copy constructor because it would then modify an initialized immutable field. However, with opAssign the compiler knows that A.a cannot be modified because it is immutable.
Jul 11 2018
On Wed, 11 Jul 2018 at 00:40, RazvanN via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Tuesday, 10 July 2018 at 20:58:09 UTC, Manu wrote:What's wrong with: struct S { this(ref S copyFrom); } That looks like a perfectly good copy constructor declaration ;) I'm just saying, the DIP needs to explain this.On Tue, 10 Jul 2018 at 03:50, RazvanN via Digitalmars-d <digitalmars-d puremagic.com> wrote:It is a simple way of defining a copy constructor without the need of adding new keywords and with minimal additions to the parser.Hi everyone! I managed to put together a first draft of the DIP for adding the copy constructor to the language [1]. If anyone is interested, please take a look. Suggestions and comments about technical aspects and wording are all welcome. Thanks, RazvanN [1] https://github.com/dlang/DIPs/pull/129I feel there's some things missing. 1. Explain the need and reasoning behind ` implicit`... that's weirdRight. This is all obvious and intuitive. What I'm hearing is that under this proposal, copy constructors and assignment operators DO come in pairs (just like in C++), but that's not mentioned here in this DIP. Since this proposal will introduce that recommended pattern from C++, it may be worth mentioning.and I don't like it at face value. 2. It looks like copy constructors are used to perform assignments (and not constructions)... but, there is also opAssign. What gives? Eg: S b = a; // <- copy construction? looks like an assignment. And not: S b = S(a); // <- actually looks like a construction, but this syntax seems to not be intended (and rightly so, it's pretty terrible) 3. In C++, copy constructors and copy assignment operators come in pairs (which is totally lame!), but we don't see that same pattern extend here, and it's not clear at all why. 4. Given the special rules where assignments are lifted to constructions, I want to know when that occurs (maybe that is already spec-ed wrt postblit?) - ManuCopy construction is used solely when the object was not initialized and it cannot be used otherwise. Consider this example: struct A { immutable int a = 7; implicit this(ref A another) { this.a = A.a; // first assignment over .init state - ok } void opAssign(A rhs) { this.a = rhs.a; } } void main() { A a = A(2); A b = a; // initialization -> calls copy constructor b = a; // cannot call copy constructor because it will // modify immutable; call opAssign. } The first assignment of b calls the copy constructor and the immutable field is initialized; later assignments to b.a will result in "modify immutable" error. The second assignment of b cannot call the copy constructor because it would then modify an initialized immutable field. However, with opAssign the compiler knows that A.a cannot be modified because it is immutable.
Jul 11 2018
What's wrong with: struct S { this(ref S copyFrom); } That looks like a perfectly good copy constructor declaration ;) I'm just saying, the DIP needs to explain this.That is actually a valid constructor, according to today's compiler. There might be code out there that uses this syntax for the constructor and overnight it will be turned into a copy constructor. I agree that the current syntax is lacking. This was Andrei's proposition and I was initially against it, but he said to put it in the DIP so that we can discuss it as a community. Maybe this syntax is better: this(ref S a another) It looks like the c++ copy constructor but the ` ` makes it different from a constructor, so we're good. What do you think?Right. This is all obvious and intuitive. What I'm hearing is that under this proposal, copy constructors and assignment operators DO come in pairs (just like in C++), but that's not mentioned here in this DIP. Since this proposal will introduce that recommended pattern from C++, it may be worth mentioning.If by "come in pairs" you mean that you can define them both, then yes, that is the case. Will add a paragraph in the DIP to specify this. You mentioned that it's terrible that the assignment operator and the copy constructor come in pairs. Why is that? Would you rather have a copy constructor that is used also as an assignment operator?
Jul 11 2018
On 07/12/2018 02:54 AM, RazvanN wrote:We will not add syntax if we can help it.What's wrong with: struct S { this(ref S copyFrom); } That looks like a perfectly good copy constructor declaration ;) I'm just saying, the DIP needs to explain this.That is actually a valid constructor, according to today's compiler. There might be code out there that uses this syntax for the constructor and overnight it will be turned into a copy constructor. I agree that the current syntax is lacking. This was Andrei's proposition and I was initially against it, but he said to put it in the DIP so that we can discuss it as a community. Maybe this syntax is better: this(ref S a another) It looks like the c++ copy constructor but the ` ` makes it different from a constructor, so we're good. What do you think?
Jul 12 2018
Am Thu, 12 Jul 2018 09:48:37 -0400 schrieb Andrei Alexandrescu:We have this(this) for postblits so how about this(ref this a) for copy constructors? Unfortunately this is currently valid code and compiles: this is treated as typeof(this). However, we have already deprecated that, so maybe we can reuse the syntax? It should be a quite consistent evolution from this(this). (Another option is this(ref this A a) which does not conflict with existing syntax). -- JohannesI agree that the current syntax is lacking. This was Andrei's proposition and I was initially against it, but he said to put it in the DIP so that we can discuss it as a community. Maybe this syntax is better: this(ref S a another) It looks like the c++ copy constructor but the ` ` makes it different from a constructor, so we're good. What do you think?We will not add syntax if we can help it.
Jul 12 2018
Am Thu, 12 Jul 2018 17:32:06 +0000 schrieb Johannes Pfau:Am Thu, 12 Jul 2018 09:48:37 -0400 schrieb Andrei Alexandrescu:I just read your other replies Andrei. I guess if we're ever going use the same syntax for implicit conversions, the implicit syntax is indeed consistent and logical. As long as it's only used for copy-ctors the name feels 'strange'. -- JohannesWe have this(this) for postblits so how about this(ref this a) for copy constructors? Unfortunately this is currently valid code and compiles: this is treated as typeof(this). However, we have already deprecated that, so maybe we can reuse the syntax? It should be a quite consistent evolution from this(this). (Another option is this(ref this A a) which does not conflict with existing syntax).I agree that the current syntax is lacking. This was Andrei's proposition and I was initially against it, but he said to put it in the DIP so that we can discuss it as a community. Maybe this syntax is better: this(ref S a another) It looks like the c++ copy constructor but the ` ` makes it different from a constructor, so we're good. What do you think?We will not add syntax if we can help it.
Jul 12 2018
On Thursday, 12 July 2018 at 06:54:37 UTC, RazvanN wrote:[...]If by "come in pairs" you mean that you can define them both, then yes, that is the case. Will add a paragraph in the DIP to specify this. You mentioned that it's terrible that the assignment operator and the copy constructor come in pairs. Why is that? Would you rather have a copy constructor that is used also as an assignment operator?Because, like in C++, now you have to implement both and make sure they do the same thing. Boilerplaty and a recipe for disaster. Atila
Jul 12 2018
On 07/12/2018 09:49 AM, Atila Neves wrote:On Thursday, 12 July 2018 at 06:54:37 UTC, RazvanN wrote:There's no meaningful way to avoid that. The two operations are fundamentally different, are typechecked differently, and actually are different in the presence of qualifiers on fields. Introspection is a key helper here compared to C++.[...]If by "come in pairs" you mean that you can define them both, then yes, that is the case. Will add a paragraph in the DIP to specify this. You mentioned that it's terrible that the assignment operator and the copy constructor come in pairs. Why is that? Would you rather have a copy constructor that is used also as an assignment operator?Because, like in C++, now you have to implement both and make sure they do the same thing. Boilerplaty and a recipe for disaster. Atila
Jul 12 2018
On Thu, 12 Jul 2018 at 07:15, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 07/12/2018 09:49 AM, Atila Neves wrote:As I've said elsewhere, opAssign() can be fabricated by: this.destroy(); emplace(&this, copyFrom); We should consider fabricating an implicit assignment operator in the presence of an elaborate copy constructor. As you say, this interacts with qualifiers... I don't think it's trivial, but I think it should be explored. Otherwise whenever anyone forgets to implement an assignment operator, it'll just blit, which is almost certainly incorrect.On Thursday, 12 July 2018 at 06:54:37 UTC, RazvanN wrote:There's no meaningful way to avoid that. The two operations are fundamentally different, are typechecked differently, and actually are different in the presence of qualifiers on fields. Introspection is a key helper here compared to C++.[...]If by "come in pairs" you mean that you can define them both, then yes, that is the case. Will add a paragraph in the DIP to specify this. You mentioned that it's terrible that the assignment operator and the copy constructor come in pairs. Why is that? Would you rather have a copy constructor that is used also as an assignment operator?Because, like in C++, now you have to implement both and make sure they do the same thing. Boilerplaty and a recipe for disaster. Atila
Jul 12 2018
On 7/12/18 6:37 PM, Manu wrote:On Thu, 12 Jul 2018 at 07:15, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:Not if the object has immutable fields, is immutable itself, is assigned from an immutable object and has non-immutable indirections, etc. One issue the DIP is addressing carefully is copying across qualifier combinations. It also emphasizes how the current postblit fails at that.On 07/12/2018 09:49 AM, Atila Neves wrote:As I've said elsewhere, opAssign() can be fabricated by: this.destroy(); emplace(&this, copyFrom);On Thursday, 12 July 2018 at 06:54:37 UTC, RazvanN wrote:There's no meaningful way to avoid that. The two operations are fundamentally different, are typechecked differently, and actually are different in the presence of qualifiers on fields. Introspection is a key helper here compared to C++.[...]If by "come in pairs" you mean that you can define them both, then yes, that is the case. Will add a paragraph in the DIP to specify this. You mentioned that it's terrible that the assignment operator and the copy constructor come in pairs. Why is that? Would you rather have a copy constructor that is used also as an assignment operator?Because, like in C++, now you have to implement both and make sure they do the same thing. Boilerplaty and a recipe for disaster. AtilaWe should consider fabricating an implicit assignment operator in the presence of an elaborate copy constructor.Not in this DIP.As you say, this interacts with qualifiers... I don't think it's trivial, but I think it should be explored. Otherwise whenever anyone forgets to implement an assignment operator, it'll just blit, which is almost certainly incorrect.Exploring is of course welcome. Are you talking about the D language? Assignment never did just blit, and this DIP does not propose that. Andrei
Jul 12 2018
On Wed, 11 Jul 2018 at 23:55, RazvanN via Digitalmars-d <digitalmars-d puremagic.com> wrote:Exactly. Is that a problem? It probably IS a copy constructor already, what else could it be? :)What's wrong with: struct S { this(ref S copyFrom); } That looks like a perfectly good copy constructor declaration ;) I'm just saying, the DIP needs to explain this.That is actually a valid constructor, according to today's compiler. There might be code out there that uses this syntax for the constructor and overnight it will be turned into a copy constructor.I agree that the current syntax is lacking. This was Andrei's proposition and I was initially against it, but he said to put it in the DIP so that we can discuss it as a community. Maybe this syntax is better: this(ref S a another) It looks like the c++ copy constructor but the ` ` makes it different from a constructor, so we're good. What do you think?I would struggle to get behind anything other than `this(ref T)` 1. There's an extremely low probability such a function exists in any code, because it's redundant in the current language (postblit) 2. If it does exist, there's an extremely low probability that it's not already a valid copy constructor (what else could it possibly be?!) 3. The remaining cases are crazy. extremely^^2 low probability of causing an issue is not worth butchering the syntax for all time to come... if you ask me. Can the DIP identify a couple of trouble cases and present as motivation for the silly syntax? If no such cases can be identified, then it's hard to support an argument in favour.Well, in C++ they SHOULD come in pairs. Things don't work if they don't, and I expect the same truth will emerge here. I'd like to see the DIP explore the parallel; understand why C++ specifies that they must come in pairs, and then explain that the same reasons also apply to D, or why they don't. Does dlang now have the 'rule-of-3' (or 5 now in c++11)?Right. This is all obvious and intuitive. What I'm hearing is that under this proposal, copy constructors and assignment operators DO come in pairs (just like in C++), but that's not mentioned here in this DIP. Since this proposal will introduce that recommended pattern from C++, it may be worth mentioning.If by "come in pairs" you mean that you can define them both, then yes, that is the case. Will add a paragraph in the DIP to specify this.You mentioned that it's terrible that the assignment operator and the copy constructor come in pairs. Why is that? Would you rather have a copy constructor that is used also as an assignment operator?It's pretty lame that C++ requires you to effectively write the same function twice in 2 different ways. It might be nice to explore if there's any way to unify them... I often define C++ assignment operators like this to save on code duplication: T& operator=(const T& rh) { this->~T(); new(this) T(rh); } I would hate to see this emerge as a pattern: void opAssign(ref T rh) { this.destroy(); emplace(&this, rh); } Being able to implement them both independently is *occasionally* useful, but 95% of the time, destruct + copy-construct is an equally efficient implementation for assignment. I'd suggest that this destruct+copy-construct pattern is a perfectly good substitute for assignment in most cases, and maybe the compiler should deploy the pattern as an implicit copy constructor in lieu of an explicit one? So, if the user specifies a complex copy constructor, but no assignment operator (which just blits on copy), then they've almost certainly introduced a bug on copying! Perhaps the compiler should automatically emit an assignment operator implemented as above in presence of a (suite of? [const/immutable/etc permutations]) 'complex' copy constructor?
Jul 12 2018
On 7/12/18 4:29 PM, Manu wrote:Being able to implement them both independently is*occasionally* useful, but 95% of the time, destruct + copy-construct is an equally efficient implementation for assignment. I'd suggest that this destruct+copy-construct pattern is a perfectly good substitute for assignment in most cases, and maybe the compiler should deploy the pattern as an implicit copy constructor in lieu of an explicit one? So, if the user specifies a complex copy constructor, but no assignment operator (which just blits on copy), then they've almost certainly introduced a bug on copying! Perhaps the compiler should automatically emit an assignment operator implemented as above in presence of a (suite of? [const/immutable/etc permutations]) 'complex' copy constructor?Not the charter of the current DIP.
Jul 12 2018
On Thu, 12 Jul 2018 at 18:25, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 7/12/18 4:29 PM, Manu wrote:In a post-blit world, with no opAssign specified, postblit will call for copy construction AND for assignment, thereby assignment is always correct. Once postblit is swapped for a copy-constructor, absence of opAssign will result in invalid behaviour on assignment. Introduction of copy constructor breaks default assignment, it needs to address it somehow. I think my suggestion is the only practical solution.Being able to implement them both independently is*occasionally* useful, but 95% of the time, destruct + copy-construct is an equally efficient implementation for assignment. I'd suggest that this destruct+copy-construct pattern is a perfectly good substitute for assignment in most cases, and maybe the compiler should deploy the pattern as an implicit copy constructor in lieu of an explicit one? So, if the user specifies a complex copy constructor, but no assignment operator (which just blits on copy), then they've almost certainly introduced a bug on copying! Perhaps the compiler should automatically emit an assignment operator implemented as above in presence of a (suite of? [const/immutable/etc permutations]) 'complex' copy constructor?Not the charter of the current DIP.
Jul 12 2018
On 7/12/18 10:05 PM, Manu wrote:On Thu, 12 Jul 2018 at 18:25, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:Affirmative. The DIP needs to specify how assignment is handled if no opAssign is present but a copy ctor is present. Thanks!On 7/12/18 4:29 PM, Manu wrote:In a post-blit world, with no opAssign specified, postblit will call for copy construction AND for assignment, thereby assignment is always correct. Once postblit is swapped for a copy-constructor, absence of opAssign will result in invalid behaviour on assignment. Introduction of copy constructor breaks default assignment, it needs to address it somehow. I think my suggestion is the only practical solution.Being able to implement them both independently is*occasionally* useful, but 95% of the time, destruct + copy-construct is an equally efficient implementation for assignment. I'd suggest that this destruct+copy-construct pattern is a perfectly good substitute for assignment in most cases, and maybe the compiler should deploy the pattern as an implicit copy constructor in lieu of an explicit one? So, if the user specifies a complex copy constructor, but no assignment operator (which just blits on copy), then they've almost certainly introduced a bug on copying! Perhaps the compiler should automatically emit an assignment operator implemented as above in presence of a (suite of? [const/immutable/etc permutations]) 'complex' copy constructor?Not the charter of the current DIP.
Jul 12 2018
Indeed, but this was the source of the problem also, because you could modify immutable fields that way.In a post-blit world, with no opAssign specified, postblit will call for copy construction AND for assignment, thereby assignment is always correct. Once postblit is swapped for a copy-constructor, absence of opAssign will result in invalid behaviour on assignment.The difference between a copy constructor and opAssign is how the type checking is performed. This leads to situations where a copy constructor is not suitable as an assignment operator. However, if a copy constructor is defined in a way that is correctly type checked both as a constructor and as a normal function, then there is no problem in using the copy constructor for assignments: struct A { immutable int b; int c; implicit this(ref A rhs) { this.c = rhs.c; } } struct B { immutable int b; int c; implicit this(ref A rhs) { this.b = rhs.b; this.c = rhs.c; } } void main() { A a, c; A b = a; b = c; // no problem in calling copy constructor, immutable is // not modified B d, e; B f = d; f = d; // cannot use copy constructor because it will modify immutable // field B.b; for this situation you need an opAssign to specify // how the assignment is dealt with. } The problem with this approach is that some copy constructors will also be used as assignment operators while others will not, but with good error messages it could be handled (error on line `f = d` : opAssign not specified and the copy constructor is not suitable for assignments because it modifies immutable field `b`). What are your opinions on this?Introduction of copy constructor breaks default assignment, it needs to address it somehow. I think my suggestion is the only practical solution.Affirmative. The DIP needs to specify how assignment is handled if no opAssign is present but a copy ctor is present. Thanks!
Jul 13 2018
The above code contains a typo. The parameter type of the second copy constructor is meant to be B not A
Jul 13 2018
On Fri, 13 Jul 2018 at 04:05, RazvanN via Digitalmars-d <digitalmars-d puremagic.com> wrote:Right; I figure, if the struct contains members that can't be copied, then the struct is defined in such a way that it simply can't be copied. I mean, if the copy constructor can't be used to copy the thing, then is copying the struct valid at all? What would a valid copy operation on a struct with an immutable field do? Either way, in that case, a good error should inform the user they need to write an explicit opAssign.[...]The problem with this approach is that some copy constructors will also be used as assignment operators while others will not, but with good error messages it could be handled (error on line `f = d` : opAssign not specified and the copy constructor is not suitable for assignments because it modifies immutable field `b`). What are your opinions on this?
Jul 13 2018
On Friday, 13 July 2018 at 11:02:57 UTC, RazvanN wrote:...Indeed, but this was the source of the problem also, because you could modify immutable fields that way.[...]The difference between a copy constructor and opAssign is how the type checking is performed. This leads to situations where a copy constructor is not suitable as an assignment operator. However, if a copy[...]Affirmative. The DIP needs to specify how assignment is handled if no opAssign is present but a copy ctor is present. Thanks!What are your opinions on this?What about going the other way? Can you use the unqualified opAssign as the unqualified copy constructor? I assume these implicit copy constructors are normal constructors.
Jul 15 2018
On Thursday, 12 July 2018 at 20:29:43 UTC, Manu wrote:On Wed, 11 Jul 2018 at 23:55, RazvanN via Digitalmars-d <digitalmars-d puremagic.com> wrote:it can be something else. For example a lifo list pusher. Even if it is considered bad design, someone might have done itExactly. Is that a problem? It probably IS a copy constructor already, what else could it be? :)What's wrong with: struct S { this(ref S copyFrom); } That looks like a perfectly good copy constructor declaration ;) I'm just saying, the DIP needs to explain this.That is actually a valid constructor, according to today's compiler. There might be code out there that uses this syntax for the constructor and overnight it will be turned into a copy constructor.
Jul 13 2018
On 07/11/2018 05:28 PM, Manu wrote:What's wrong with: struct S { this(ref S copyFrom); } That looks like a perfectly good copy constructor declaration ;) I'm just saying, the DIP needs to explain this.Thanks, worth a paragraph discussing silent semantics change.Right. This is all obvious and intuitive. What I'm hearing is that under this proposal, copy constructors and assignment operators DO come in pairs (just like in C++), but that's not mentioned here in this DIP. Since this proposal will introduce that recommended pattern from C++, it may be worth mentioning.Shouldn't hurt to add 1-2 sentences to the effect. (Also an example.)
Jul 12 2018
On 07/10/2018 04:58 PM, Manu wrote:On Tue, 10 Jul 2018 at 03:50, RazvanN via Digitalmars-d <digitalmars-d puremagic.com> wrote:Razvan: I think it would help to explain that the attribute is necessary to avoid changing semantics of existing code. Thanks.Hi everyone! I managed to put together a first draft of the DIP for adding the copy constructor to the language [1]. If anyone is interested, please take a look. Suggestions and comments about technical aspects and wording are all welcome. Thanks, RazvanN [1] https://github.com/dlang/DIPs/pull/129I feel there's some things missing. 1. Explain the need and reasoning behind ` implicit`.3. In C++, copy constructors and copy assignment operators come in pairs (which is totally lame!), but we don't see that same pattern extend here, and it's not clear at all why.The proposal does not affect or interfere with opAssign in any way.4. Given the special rules where assignments are lifted to constructions, I want to know when that occurs (maybe that is already spec-ed wrt postblit?)What special rules are you referring to? Thanks.
Jul 12 2018
On 07/12/2018 03:40 PM, Andrei Alexandrescu wrote:On 07/10/2018 04:58 PM, Manu wrote:[...]You're still potentially changing the semantics of existing code. ` implicit` can be a UDA today: ---- enum implicit = 0; struct C { implicit this(ref C another) {} } ---- Today, that's a normal constructor. With the DIP, it becomes a copy constructor.1. Explain the need and reasoning behind ` implicit`.Razvan: I think it would help to explain that the attribute is necessary to avoid changing semantics of existing code. Thanks.
Jul 12 2018
On 7/12/18 2:30 PM, ag0aep6g wrote:On 07/12/2018 03:40 PM, Andrei Alexandrescu wrote:That is correct and a liability of the current DIP. That should be mentioned in it.On 07/10/2018 04:58 PM, Manu wrote:[...]You're still potentially changing the semantics of existing code. ` implicit` can be a UDA today: ---- enum implicit = 0; struct C { implicit this(ref C another) {} } ---- Today, that's a normal constructor. With the DIP, it becomes a copy constructor.1. Explain the need and reasoning behind ` implicit`.Razvan: I think it would help to explain that the attribute is necessary to avoid changing semantics of existing code. Thanks.
Jul 12 2018
On Friday, 13 July 2018 at 01:18:48 UTC, Andrei Alexandrescu wrote:On 7/12/18 2:30 PM, ag0aep6g wrote:That's easily fixed by implementing a compiler recognized UDA. That would mean that it would only be a copy constructor if "implicit" is defined in core.attribute. This would also avoid any special syntax in the parser. The already existing selector is implemented like this. -- /Jacob CarlborgYou're still potentially changing the semantics of existing code. ` implicit` can be a UDA today: ---- enum implicit = 0; struct C { implicit this(ref C another) {} } ---- Today, that's a normal constructor. With the DIP, it becomes a copy constructor.That is correct and a liability of the current DIP. That should be mentioned in it.
Jul 14 2018
On 7/14/18 11:26 AM, Jacob Carlborg wrote:On Friday, 13 July 2018 at 01:18:48 UTC, Andrei Alexandrescu wrote:Affirmative. We're going that route, similar to " safe" and " nogc".On 7/12/18 2:30 PM, ag0aep6g wrote:That's easily fixed by implementing a compiler recognized UDA. That would mean that it would only be a copy constructor if "implicit" is defined in core.attribute. This would also avoid any special syntax in the parser. The already existing selector is implemented like this.You're still potentially changing the semantics of existing code. ` implicit` can be a UDA today: ---- enum implicit = 0; struct C { implicit this(ref C another) {} } ---- Today, that's a normal constructor. With the DIP, it becomes a copy constructor.That is correct and a liability of the current DIP. That should be mentioned in it.
Jul 16 2018
On 07/16/2018 09:06 PM, Andrei Alexandrescu wrote:On 7/14/18 11:26 AM, Jacob Carlborg wrote:[...]safe and nogc are not compiler recognized UDAs. If you implement implicit like them, then you're not doing what Jacob suggests.That's easily fixed by implementing a compiler recognized UDA. That would mean that it would only be a copy constructor if "implicit" is defined in core.attribute. This would also avoid any special syntax in the parser. The already existing selector is implemented like this.Affirmative. We're going that route, similar to " safe" and " nogc".
Jul 16 2018
On 7/16/18 3:12 PM, ag0aep6g wrote:On 07/16/2018 09:06 PM, Andrei Alexandrescu wrote:Then "negative" :o). In brief implicit follows the same implementation as safe and nogc/On 7/14/18 11:26 AM, Jacob Carlborg wrote:[...]safe and nogc are not compiler recognized UDAs. If you implement implicit like them, then you're not doing what Jacob suggests.That's easily fixed by implementing a compiler recognized UDA. That would mean that it would only be a copy constructor if "implicit" is defined in core.attribute. This would also avoid any special syntax in the parser. The already existing selector is implemented like this.Affirmative. We're going that route, similar to " safe" and " nogc".
Jul 16 2018
On Tuesday, 17 July 2018 at 00:04:12 UTC, Andrei Alexandrescu wrote:Then "negative" :o). In brief implicit follows the same implementation as safe and nogc/Why? This is a breaking change. Why not go with an approach that does not cause any breaking changes, which is just as easy to do? It also doesn't required any special casing in the parser. This is how selector is implemented. -- /Jacob Carlborg
Jul 17 2018
On Tuesday, 17 July 2018 at 07:27:32 UTC, Jacob Carlborg wrote:On Tuesday, 17 July 2018 at 00:04:12 UTC, Andrei Alexandrescu wrote:Can you explain a bit more here? How does having implicit as a compiler recognized UDA avoid breaking changes as opposed to it being implemented like nogc/ safe (how are those implemented differently anyway?) Cheers, - AliThen "negative" :o). In brief implicit follows the same implementation as safe and nogc/Why? This is a breaking change. Why not go with an approach that does not cause any breaking changes, which is just as easy to do? It also doesn't required any special casing in the parser. This is how selector is implemented. -- /Jacob Carlborg
Jul 17 2018
On 07/17/2018 03:03 PM, aliak00 wrote:Can you explain a bit more here? How does having implicit as a compiler recognized UDA avoid breaking changes as opposed to it being implemented like nogc/ safe (how are those implemented differently anyway?)In a UDA ` implicit`, `implicit` is just a normal symbol. So the normal lookup rules apply. In particular, you can shadow an imported `implicit` with a local one: --- object.d enum implicit = 1; /* Actual implementation would be different. */ --- bar.d /* invisible default `import object` here */ implicit void f() {} static assert(__traits(getAttributes, f)[0] == 1); /* Passes. `object.implicit` is used. */ --- baz.d /* invisible default `import object` here */ enum implicit = 2; implicit void f() {} static assert(__traits(getAttributes, f)[0] == 2); /* Passes. The local `implicit` is used. */ You can't do that with ` safe`, because ` safe` is not a UDA, and `safe` is not a symbol there. ` safe` is special syntax, recognized as a whole by the parser. No symbol lookup is happening. You can see the difference if you change all occurrences of "implicit" to "safe" in that code. Won't work. As for breakage, baz.d is working code today. With ` implicit` as a UDA, it keeps working in the same way. With ` implicit` as a new non-UDA attribute, it will change its meaning, and the assert will fail.
Jul 17 2018
On Tuesday, 17 July 2018 at 14:41:06 UTC, ag0aep6g wrote:On 07/17/2018 03:03 PM, aliak00 wrote:Ah, gotcha! Thank you![...]In a UDA ` implicit`, `implicit` is just a normal symbol. So the normal lookup rules apply. In particular, you can shadow an imported `implicit` with a local one: [...]
Jul 17 2018
On Tuesday, 10 July 2018 14:58:09 MDT Manu via Digitalmars-d wrote:2. It looks like copy constructors are used to perform assignments (and not constructions)... but, there is also opAssign. What gives? Eg: S b = a; // <- copy construction? looks like an assignment. And not: S b = S(a); // <- actually looks like a construction, but this syntax seems to not be intended (and rightly so, it's pretty terrible)S b = a; has never been assignment in either C++ or D. It's initialization / construction, which means that it calls a constructor - be that a postblit constructor or a copy constructor. Assignment only occurs when you're giving an existing object a new value. And why would S b = S(a); not be intended? Sure, it's kind of pointless if a is an S, but if you have a copy constructor, it makes perfect sense that S(a) would work and would be pretty bizarre if it didn't, since it's explicitly calling the copy constructor. It even works right now if you give S a constructor that takes an S. It just isn't actually treated as a proper copy constructor at the moment, since that's currently the postblit constructor's job. - Jonathan M Davis
Jul 10 2018
On Tue, 10 Jul 2018 at 15:23, Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Tuesday, 10 July 2018 14:58:09 MDT Manu via Digitalmars-d wrote:I know this, but it's not syntactically obvious, it just depends on the fact that you already know that fact... I feel a DIP about copy construction needs to have some text explaining that, and where the edges are. Is an initialisation assignment can use a copy constructor, why can't a normal assignment implicitly use a copy constructor? (implicit destruct then copy-construct)2. It looks like copy constructors are used to perform assignments (and not constructions)... but, there is also opAssign. What gives? Eg: S b = a; // <- copy construction? looks like an assignment. And not: S b = S(a); // <- actually looks like a construction, but this syntax seems to not be intended (and rightly so, it's pretty terrible)S b = a; has never been assignment in either C++ or D. It's initialization / construction, which means that it calls a constructor - be that a postblit constructor or a copy constructor. Assignment only occurs when you're giving an existing object a new value.And why would S b = S(a); not be intended? Sure, it's kind of pointless if a is an S, but if you have a copy constructor, it makes perfect sense that S(a) would work and would be pretty bizarre if it didn't, since it's explicitly calling the copy constructor.But there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?It even works right now if you give S a constructor that takes an S. It just isn't actually treated as a proper copy constructor at the moment, since that's currently the postblit constructor's job.Current language doesn't have ` implicit` written anywhere...
Jul 10 2018
But there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?The implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object.
Jul 11 2018
On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:How is this different from other types of constructors or destructors? I also very much dislike the syntax - it makes no sense to me at all. I commented on the PR itself asking why it differs so much from C++ - specifically, what's bad about the C++ way of doing things there that we want to avoid? AtilaBut there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?The implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object.
Jul 11 2018
On 07/11/2018 11:11 AM, Atila Neves wrote:On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:The main difference is that the compiler may insert calls to it implicitly.How is this different from other types of constructors or destructors?But there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?The implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object.I also very much dislike the syntax - it makes no sense to me at all. I commented on the PR itself asking why it differs so much from C++ - specifically, what's bad about the C++ way of doing things there that we want to avoid?C++ is at the other end of the spectrum - constructors are too implicit, so the "explicit" keyword has been introduced with the advice to use it in the vast majority of cases. If C++ could do it again, it would make everything explicit and add an "implicit" keyword.
Jul 12 2018
On Thursday, 12 July 2018 07:45:30 MDT Andrei Alexandrescu via Digitalmars-d wrote:That's only an issue in C++, because C++ uses constructors for implicit conversions unless you mark them with explicit. D doesn't ever do implicit conversions like that. All constructors are effectively explicit. Is this DIP proposing that we add such implicit conversions? Because if it is, that's a pretty major change that arguably has nothing to do with copy constructors, since copy constructors are for constructing an object from another object of the same type (though possibly of different mutability), not from objects of other types. That would just be a normal constructor. I really don't understand what the purpose of implicit is here. What's the problem of just going off of the type of the constructor's single parameter to determine whether it's a copy constructor? - Jonathan M DavisI also very much dislike the syntax - it makes no sense to me at all. I commented on the PR itself asking why it differs so much from C++ - specifically, what's bad about the C++ way of doing things there that we want to avoid?C++ is at the other end of the spectrum - constructors are too implicit, so the "explicit" keyword has been introduced with the advice to use it in the vast majority of cases. If C++ could do it again, it would make everything explicit and add an "implicit" keyword.
Jul 12 2018
On 07/12/2018 10:54 AM, Jonathan M Davis wrote:On Thursday, 12 July 2018 07:45:30 MDT Andrei Alexandrescu via Digitalmars-d wrote:The DIP is proposing what's in the DIP :o). We actually clarify this in text: "The type of the parameter to the copy constructor needs to be identical to typeof(this); an error is issued otherwise. This requirement may be relaxed in the future in order to accomodate implicit copying from objects of a different type:" [example follows]That's only an issue in C++, because C++ uses constructors for implicit conversions unless you mark them with explicit. D doesn't ever do implicit conversions like that. All constructors are effectively explicit. Is this DIP proposing that we add such implicit conversions?I also very much dislike the syntax - it makes no sense to me at all. I commented on the PR itself asking why it differs so much from C++ - specifically, what's bad about the C++ way of doing things there that we want to avoid?C++ is at the other end of the spectrum - constructors are too implicit, so the "explicit" keyword has been introduced with the advice to use it in the vast majority of cases. If C++ could do it again, it would make everything explicit and add an "implicit" keyword.I really don't understand what the purpose of implicit is here. What's the problem of just going off of the type of the constructor's single parameter to determine whether it's a copy constructor?That would silently change semantics of existing code, which is to be avoided. Andrei
Jul 12 2018
On Thu, 12 Jul 2018 at 06:50, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 07/11/2018 11:11 AM, Atila Neves wrote:You mean like ~this(), and op[Anything](), and front() and popFront() and empty()? I don't think we need this attribute.On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:The main difference is that the compiler may insert calls to it implicitly.How is this different from other types of constructors or destructors?But there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?The implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object.
Jul 12 2018
On 7/12/18 6:34 PM, Manu wrote:On Thu, 12 Jul 2018 at 06:50, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:I mentioned this, and patiently will mention it again: we need to introduce the attribute so as to avoid silently changing the semantics of existing code.On 07/11/2018 11:11 AM, Atila Neves wrote:You mean like ~this(), and op[Anything](), and front() and popFront() and empty()? I don't think we need this attribute.On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:The main difference is that the compiler may insert calls to it implicitly.How is this different from other types of constructors or destructors?But there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?The implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object.
Jul 12 2018
On Thu, 12 Jul 2018 at 19:15, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 7/12/18 6:34 PM, Manu wrote:Take this reply while assuming a no- implicit world, which I think is still a reasonable option (although I support introduction of implicit in my other recent replies): Don't be condescending. I asked, and I will "patiently" ask again, What existing code are you changing the semantics of? It's still not clear to me how accepting `this(ref T)` as a magic signature that is a copy constructor can break existing code? Is it the unlikely^^2 case that the function exists somewhere and doesn't perform copy construction? 1. the function is highly unlikely to exist because postblit; it's a meaningless function to write. are there any known instances of that signature in the wild? 2. if the function does exist, it's highly unlikely that it doesn't perform a valid copy construction; what else could it possibly do? 3. remaining cases are broken by this DIP, but they are probably crazy and deserve to be deprecated! Is there any reasonable existing use of the signature that would be legitimately broken by being invoked implicitly? I feel like there's something that I'm missing... but if there's not, then just change the semantic. I reason; copy construction is something so fundamental. It will be written by basically every programmer with relative high frequently, and adding awkward syntax or weird language baggage to the concept feels like a very poor choice. By contrast, if there's 1 user out there who used the copy-constructor signature to do some weird thing other than copy construction, and their code is broken by this change, his use case does not balance the imposition applied to every implementation of copy constructor forever from this time forward. This is so much more important than that, it's extremely fundamental language stuff, and needs to be as friction-less as possible, and it should certainly not reek of legacy drama.On Thu, 12 Jul 2018 at 06:50, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:I mentioned this, and patiently will mention it again: we need to introduce the attribute so as to avoid silently changing the semantics of existing code.On 07/11/2018 11:11 AM, Atila Neves wrote:You mean like ~this(), and op[Anything](), and front() and popFront() and empty()? I don't think we need this attribute.On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:The main difference is that the compiler may insert calls to it implicitly.How is this different from other types of constructors or destructors?But there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?The implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object.
Jul 12 2018
On Friday, 13 July 2018 at 03:01:25 UTC, Manu wrote:On Thu, 12 Jul 2018 at 19:15, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:https://github.com/search?q=%22this%5C%28ref%22+language%3AD&type=Code The answer seems to be: not many. Most of the results above are false positives because github won't let me escape the left parenthesis. AtilaOn 7/12/18 6:34 PM, Manu wrote:[..] doesn't perform copy construction? 1. the function is highly unlikely to exist because postblit; it's a meaningless function to write. are there any known instances of that signature in the wild?On Thu, 12 Jul 2018 at 06:50, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:
Jul 13 2018
On 7/13/18 8:31 AM, Atila Neves wrote:On Friday, 13 July 2018 at 03:01:25 UTC, Manu wrote:A proposal that just works without any user intervention would definitely be attractive. The drawback is silent modification of code behavior. Consider: import std.stdio; struct A { this(ref immutable A obj) { writeln("x"); } } void main() { immutable A a1; A a2 = A(a1); A a3 = a1; } With the current language, "x" is printed once. If we make the ctor implicit, "x" is printed twice. In the "levels of hell" of semantics changes, probably the nicest is allowing code to compile that previously didn't. Then, refusing to compile code that previously did would be definitely bad. But if you want to drink the cup of disgrace to the bottom, you must reach for silent change of behavior.On Thu, 12 Jul 2018 at 19:15, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:https://github.com/search?q=%22this%5C%28ref%22+language%3AD&type=Code The answer seems to be: not many. Most of the results above are false positives because github won't let me escape the left parenthesis.On 7/12/18 6:34 PM, Manu wrote:[..] doesn't perform copy construction? 1. the function is highly unlikely to exist because postblit; it's a meaningless function to write. are there any known instances of that signature in the wild?On Thu, 12 Jul 2018 at 06:50, Andrei Alexandrescu via >Digitalmars-d <digitalmars-d puremagic.com> wrote:
Jul 13 2018
On Friday, 13 July 2018 at 14:12:59 UTC, Andrei Alexandrescu wrote:On 7/13/18 8:31 AM, Atila Neves wrote:I agree on the levels of hell. I wasn't aware the kind of change above would happen - methinks it should be in the DIP. I think I now even understand why ` implicit` is there to begin with. I still think it's confusing, so imagine someone new to the language. AtilaOn Friday, 13 July 2018 at 03:01:25 UTC, Manu wrote:A proposal that just works without any user intervention would definitely be attractive. The drawback is silent modification of code behavior. Consider: import std.stdio; struct A { this(ref immutable A obj) { writeln("x"); } } void main() { immutable A a1; A a2 = A(a1); A a3 = a1; } With the current language, "x" is printed once. If we make the ctor implicit, "x" is printed twice. In the "levels of hell" of semantics changes, probably the nicest is allowing code to compile that previously didn't. Then, refusing to compile code that previously did would be definitely bad. But if you want to drink the cup of disgrace to the bottom, you must reach for silent change of behavior.[...]https://github.com/search?q=%22this%5C%28ref%22+language%3AD&type=Code The answer seems to be: not many. Most of the results above are false positives because github won't let me escape the left parenthesis.
Jul 13 2018
On 7/13/18 11:14 AM, Atila Neves wrote:On Friday, 13 July 2018 at 14:12:59 UTC, Andrei Alexandrescu wrote:Great. Razvan, can you please add this example with discussion to the DIP (probably at the end of the Motivation section as an explanation why we need the addition of implicit). Thanks.On 7/13/18 8:31 AM, Atila Neves wrote:I agree on the levels of hell. I wasn't aware the kind of change above would happen - methinks it should be in the DIP.On Friday, 13 July 2018 at 03:01:25 UTC, Manu wrote:A proposal that just works without any user intervention would definitely be attractive. The drawback is silent modification of code behavior. Consider: import std.stdio; struct A { this(ref immutable A obj) { writeln("x"); } } void main() { immutable A a1; A a2 = A(a1); A a3 = a1; } With the current language, "x" is printed once. If we make the ctor implicit, "x" is printed twice. In the "levels of hell" of semantics changes, probably the nicest is allowing code to compile that previously didn't. Then, refusing to compile code that previously did would be definitely bad. But if you want to drink the cup of disgrace to the bottom, you must reach for silent change of behavior.[...]https://github.com/search?q=%22this%5C%28ref%22+language%3AD&type=Code The answer seems to be: not many. Most of the results above are false positives because github won't let me escape the left parenthesis.I think I now even understand why ` implicit` is there to begin with. I still think it's confusing, so imagine someone new to the language.Interesting. Coming from a C++ background makes the matter obvious because there's plenty of implicit vs. explicit discussion. To compensate for my bias - what do you think would be a better attribute name? Andrei
Jul 13 2018
On Friday, 13 July 2018 at 16:02:51 UTC, Andrei Alexandrescu wrote:On 7/13/18 11:14 AM, Atila Neves wrote:Why " implicit" is an attribute and not a keyword? -Alexander[...]Great. Razvan, can you please add this example with discussion to the DIP (probably at the end of the Motivation section as an explanation why we need the addition of implicit). Thanks.[...]Interesting. Coming from a C++ background makes the matter obvious because there's plenty of implicit vs. explicit discussion. To compensate for my bias - what do you think would be a better attribute name? Andrei
Jul 13 2018
On Friday, 13 July 2018 at 16:02:51 UTC, Andrei Alexandrescu wrote:On 7/13/18 11:14 AM, Atila Neves wrote:I came to D via C++ as well. Maybe my brain short-circuited because I saw `A a3 = a1;` in a discussion about copy constructors and assumed it would be called, and didn't realise it wouldn't have been before. I just took for granted the implicitness of the constructor call, since that's what C++ does! I wasn't even aware one could declare a C++ copy constructor `explicit` until I tried it just now. It's just not something I've ever thought about. Now that I understand the implicit call ` implicit` makes sense to me but I'm convinced it'll confuse more people than not. I'll see if I can come up with a better name. AtilaOn Friday, 13 July 2018 at 14:12:59 UTC, Andrei Alexandrescu wrote:Great. Razvan, can you please add this example with discussion to the DIP (probably at the end of the Motivation section as an explanation why we need the addition of implicit). Thanks.On 7/13/18 8:31 AM, Atila Neves wrote:I agree on the levels of hell. I wasn't aware the kind of change above would happen - methinks it should be in the DIP.On Friday, 13 July 2018 at 03:01:25 UTC, Manu wrote:A proposal that just works without any user intervention would definitely be attractive. The drawback is silent modification of code behavior. Consider: import std.stdio; struct A { this(ref immutable A obj) { writeln("x"); } } void main() { immutable A a1; A a2 = A(a1); A a3 = a1; } With the current language, "x" is printed once. If we make the ctor implicit, "x" is printed twice. In the "levels of hell" of semantics changes, probably the nicest is allowing code to compile that previously didn't. Then, refusing to compile code that previously did would be definitely bad. But if you want to drink the cup of disgrace to the bottom, you must reach for silent change of behavior.[...]https://github.com/search?q=%22this%5C%28ref%22+language%3AD&type=Code The answer seems to be: not many. Most of the results above are false positives because github won't let me escape the left parenthesis.I think I now even understand why ` implicit` is there to begin with. I still think it's confusing, so imagine someone new to the language.Interesting. Coming from a C++ background makes the matter obvious because there's plenty of implicit vs. explicit discussion. To compensate for my bias - what do you think would be a better attribute name?
Jul 13 2018
On Fri, 13 Jul 2018 at 10:35, Atila Neves via Digitalmars-d <digitalmars-d puremagic.com> wrote:[...] Now that I understand the implicit call ` implicit` makes sense to me but I'm convinced it'll confuse more people than not. I'll see if I can come up with a better name.You don't find 'implicit' satisfactory as an obvious and intuitive complement to 'explicit' in C++? I think the name's perfect, but I need to know it works in general to find it acceptable. As a marker used in this one case, it's a terrible name, as a generalised concept, it's perfect.
Jul 13 2018
On Friday, 13 July 2018 at 18:54:48 UTC, Manu wrote:As a marker used in this one case, it's a terrible name, as a generalised concept, it's perfect.Exactly.
Jul 13 2018
On Friday, 13 July 2018 at 12:31:41 UTC, Atila Neves wrote:On Friday, 13 July 2018 at 03:01:25 UTC, Manu wrote:https://www.google.no/search?q=allintext%3A+%22this%28ref%22+site%3Agithub.com+filetype%3Ad&oq=allintext%3A+%22this%28ref%22+site%3Agithub.com+filetype%3AdOn Thu, 12 Jul 2018 at 19:15, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:https://github.com/search?q=%22this%5C%28ref%22+language%3AD&type=Code The answer seems to be: not many. Most of the results above are false positives because github won't let me escape the left parenthesis. AtilaOn 7/12/18 6:34 PM, Manu wrote:[..] doesn't perform copy construction? 1. the function is highly unlikely to exist because postblit; it's a meaningless function to write. are there any known instances of that signature in the wild?On Thu, 12 Jul 2018 at 06:50, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:
Jul 17 2018
On Tue, 17 Jul 2018 at 10:20, aliak via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Friday, 13 July 2018 at 12:31:41 UTC, Atila Neves wrote:I clicked through quite a few. Every function that's a valid copy constructor by the definition here does indeed perform a valid copy construction with no side-effects, as predicted. Existing functions interpreted as copy constructors under this DIP would continue to work as intended. There's a ridiculously low probability that any such wild function that would be broken by a no-attribute version of this DIP exists.On Friday, 13 July 2018 at 03:01:25 UTC, Manu wrote:https://www.google.no/search?q=allintext%3A+%22this%28ref%22+site%3Agithub.com+filetype%3Ad&oq=allintext%3A+%22this%28ref%22+site%3Agithub.com+filetype%3AdOn Thu, 12 Jul 2018 at 19:15, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:https://github.com/search?q=%22this%5C%28ref%22+language%3AD&type=Code The answer seems to be: not many. Most of the results above are false positives because github won't let me escape the left parenthesis. AtilaOn 7/12/18 6:34 PM, Manu wrote:[..] doesn't perform copy construction? 1. the function is highly unlikely to exist because postblit; it's a meaningless function to write. are there any known instances of that signature in the wild?On Thu, 12 Jul 2018 at 06:50, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:
Jul 17 2018
On 7/12/18 11:01 PM, Manu wrote:What existing code are you changing the semantics of? It's still not clear to me how accepting `this(ref T)` as a magic signature that is a copy constructor can break existing code? Is it the unlikely^^2 case that the function exists somewhere and doesn't perform copy construction? 1. the function is highly unlikely to exist because postblit; it's a meaningless function to write. are there any known instances of that signature in the wild? 2. if the function does exist, it's highly unlikely that it doesn't perform a valid copy construction; what else could it possibly do? 3. remaining cases are broken by this DIP, but they are probably crazy and deserve to be deprecated! Is there any reasonable existing use of the signature that would be legitimately broken by being invoked implicitly? I feel like there's something that I'm missing... but if there's not, then just change the semantic. I reason; copy construction is something so fundamental. It will be written by basically every programmer with relative high frequently, and adding awkward syntax or weird language baggage to the concept feels like a very poor choice. By contrast, if there's 1 user out there who used the copy-constructor signature to do some weird thing other than copy construction, and their code is broken by this change, his use case does not balance the imposition applied to every implementation of copy constructor forever from this time forward. This is so much more important than that, it's extremely fundamental language stuff, and needs to be as friction-less as possible, and it should certainly not reek of legacy drama.Noted. So in summary you would be okay with changing semantics of existing code, under the intuition that the change is unlikely to be destructive anyway.
Jul 13 2018
On Fri, 13 Jul 2018 at 07:40, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 7/12/18 11:01 PM, Manu wrote:Yes, I think this is too important and fundamental to lug historical baggage along with it for the rest of time. That said, I'm firmly in favour of implicit, but the terms of introduction here are not satisfying. If we're going to add yet another attribute, I want to know it's a really good attribute. Adding a whole new attribute just as a marker in this case, and no clear sign that it may or may not be developed into an obvious extension of the concept (and what that looks like) is not satisfactory grounds to introduce a new attribute. I don't understand your objection to this point. I feel like you of all people should be arguing this case. If the DIP specifies introduction of an attribute, then I can't see how there's not a dependency on specification of the attribute. (That doesn't necessarily mean it must be implemented all at once, but I feel like the spec/intent should be presented up-front)What existing code are you changing the semantics of? It's still not clear to me how accepting `this(ref T)` as a magic signature that is a copy constructor can break existing code? Is it the unlikely^^2 case that the function exists somewhere and doesn't perform copy construction? 1. the function is highly unlikely to exist because postblit; it's a meaningless function to write. are there any known instances of that signature in the wild? 2. if the function does exist, it's highly unlikely that it doesn't perform a valid copy construction; what else could it possibly do? 3. remaining cases are broken by this DIP, but they are probably crazy and deserve to be deprecated! Is there any reasonable existing use of the signature that would be legitimately broken by being invoked implicitly? I feel like there's something that I'm missing... but if there's not, then just change the semantic. I reason; copy construction is something so fundamental. It will be written by basically every programmer with relative high frequently, and adding awkward syntax or weird language baggage to the concept feels like a very poor choice. By contrast, if there's 1 user out there who used the copy-constructor signature to do some weird thing other than copy construction, and their code is broken by this change, his use case does not balance the imposition applied to every implementation of copy constructor forever from this time forward. This is so much more important than that, it's extremely fundamental language stuff, and needs to be as friction-less as possible, and it should certainly not reek of legacy drama.Noted. So in summary you would be okay with changing semantics of existing code, under the intuition that the change is unlikely to be destructive anyway.
Jul 13 2018
On Thu, 12 Jul 2018 at 06:50, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 07/11/2018 11:11 AM, Atila Neves wrote:Ohhh yeah, this. I finally understand your reasoning here! Okay, that is a meaningful use for implicit, and I could get behind its introduction if it were extended to apply broadly to any constructor. If it's only used in this isolated case, and specifically disallowed in that useful broader case, it feels pointless, and probably a cause of frustration for people that expect that it should work broadly. The DIP mentions that it may be deployed broadly, but I'd like to see that resolved up-front. I could only decide to accept it in this case depending on that secondary decision.On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:The main difference is that the compiler may insert calls to it implicitly.How is this different from other types of constructors or destructors?But there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?The implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object.I also very much dislike the syntax - it makes no sense to me at all. I commented on the PR itself asking why it differs so much from C++ - specifically, what's bad about the C++ way of doing things there that we want to avoid?C++ is at the other end of the spectrum - constructors are too implicit, so the "explicit" keyword has been introduced with the advice to use it in the vast majority of cases. If C++ could do it again, it would make everything explicit and add an "implicit" keyword.
Jul 12 2018
On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:Can be explicit constructor overloaded with implicit constructor when both have same signature?But there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?The implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object.
Jul 11 2018
On Wed, 11 Jul 2018 at 09:20, vit via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:If they've got the same signature, they should do the same thing... what's the overload for?Can be explicit constructor overloaded with implicit constructor when both have same signature?But there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?The implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object.
Jul 11 2018
On 07/11/2018 12:19 PM, vit wrote:On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:Thanks for this. Yes we need to add a mention.Can be explicit constructor overloaded with implicit constructor when both have same signature?But there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?The implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object.
Jul 12 2018
On Wed, 11 Jul 2018 at 00:45, RazvanN via Digitalmars-d <digitalmars-d puremagic.com> wrote:That's my point; so this is a compile error then: S b = S(a); // <- explicit construction of copy? ie, explicit call to stated ` implicit` functionBut there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?The implicit is there to point out that you cannot call that method explicitly; it gets called for you implicitly when you construct an object as a copy of another object.
Jul 11 2018
That's my point; so this is a compile error then: S b = S(a); // <- explicit construction of copy? ie, explicit call to stated ` implicit` functionConsider this code: import std.stdio : writeln; struct S { this(this) { writeln("postblit"); } int a; this(int a) { this.a = a; } this(ref S another) { writeln("calling this"); } } void main() { S a; S b = S(a); } In this situation, the constructor is called; if `this(ref S another)` is commented the code will result in a compilation error "constructor S.this(int) is not callable using argument types (S)", so the postblit is NOT called. In my opinion this is the desired behavior and should be implemented by the copy constructor also. If you are doing `S b = S(a)` then you are explicitly trying to call a constructor; if it doesn't exist, then it's an error; if you wanted to call the copy constructor then you would have done `S b = a;`. Using S(a) states the intention of explicitly calling a constructor while the copy constructor can only be called implicitly.
Jul 12 2018
On 07/10/2018 06:50 PM, Manu wrote:On Tue, 10 Jul 2018 at 15:23, Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:The DIP is not a tutorial on existing related parts of the language. Copy initialization has been distinct from assignment for a long time in both C++ and D languages.On Tuesday, 10 July 2018 14:58:09 MDT Manu via Digitalmars-d wrote:I know this, but it's not syntactically obvious, it just depends on the fact that you already know that fact... I feel a DIP about copy construction needs to have some text explaining that, and where the edges are.2. It looks like copy constructors are used to perform assignments (and not constructions)... but, there is also opAssign. What gives? Eg: S b = a; // <- copy construction? looks like an assignment. And not: S b = S(a); // <- actually looks like a construction, but this syntax seems to not be intended (and rightly so, it's pretty terrible)S b = a; has never been assignment in either C++ or D. It's initialization / construction, which means that it calls a constructor - be that a postblit constructor or a copy constructor. Assignment only occurs when you're giving an existing object a new value.Is an initialisation assignment can use a copy constructor, why can't a normal assignment implicitly use a copy constructor? (implicit destruct then copy-construct)Because assignment and construction were, and are, distinct operation. There is no need for the DIP to explain.The " implicit" attribute does not preclude explicit calls. Razvan: you may want to mention that.And why would S b = S(a); not be intended? Sure, it's kind of pointless if a is an S, but if you have a copy constructor, it makes perfect sense that S(a) would work and would be pretty bizarre if it didn't, since it's explicitly calling the copy constructor.But there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?Misunderstanding that I assume has been cleared by now. AndreiIt even works right now if you give S a constructor that takes an S. It just isn't actually treated as a proper copy constructor at the moment, since that's currently the postblit constructor's job.Current language doesn't have ` implicit` written anywhere...
Jul 12 2018
On Thu, 12 Jul 2018 at 06:45, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 07/10/2018 06:50 PM, Manu wrote:Okay. Well, I guess that I just wanted some clarity on exactly what 'initialisation' looks like. T b = a; // clearly initialisation, sure T c = T(a); // c is initialised to a copy of an rvalue which was initialised as a copy of a. Is there *two* calls to the copy constructor here? In this way, is an explicit call to the copy constructor is allowed? You said it is, but the word " implicit" makes it look like explicit calls should be an arbitrary error; change the word at least. C++ is a disaster zone these days with `T t = x;` `T t = T(x);` `T t(x);` `T t{x};`... I just wanna make sure we don't end up with initialisation 'cases'.On Tue, 10 Jul 2018 at 15:23, Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:The DIP is not a tutorial on existing related parts of the language. Copy initialization has been distinct from assignment for a long time in both C++ and D languages.On Tuesday, 10 July 2018 14:58:09 MDT Manu via Digitalmars-d wrote:I know this, but it's not syntactically obvious, it just depends on the fact that you already know that fact... I feel a DIP about copy construction needs to have some text explaining that, and where the edges are.2. It looks like copy constructors are used to perform assignments (and not constructions)... but, there is also opAssign. What gives? Eg: S b = a; // <- copy construction? looks like an assignment. And not: S b = S(a); // <- actually looks like a construction, but this syntax seems to not be intended (and rightly so, it's pretty terrible)S b = a; has never been assignment in either C++ or D. It's initialization / construction, which means that it calls a constructor - be that a postblit constructor or a copy constructor. Assignment only occurs when you're giving an existing object a new value.Right, but as I've alluded to before, there's a loose relationship here. C++ prescribes the 'rule of 3' (or 5). If we introduce copy constructors, are we introducing those concepts? I think introduction of those concepts may pull questions about assignment into the definition space.Is an initialisation assignment can use a copy constructor, why can't a normal assignment implicitly use a copy constructor? (implicit destruct then copy-construct)Because assignment and construction were, and are, distinct operation. There is no need for the DIP to explain.Okay. In that case, I really don't like the name.The " implicit" attribute does not preclude explicit calls. Razvan: you may want to mention that.And why would S b = S(a); not be intended? Sure, it's kind of pointless if a is an S, but if you have a copy constructor, it makes perfect sense that S(a) would work and would be pretty bizarre if it didn't, since it's explicitly calling the copy constructor.But there's a super explicit ` implicit` thing written right there... so should we expect that an *explicit* call to the copy constructor is not allowed? Or maybe it is allowed and ` implicit` is a lie?
Jul 12 2018
On Tuesday, 10 July 2018 at 10:47:04 UTC, RazvanN wrote:[1] https://github.com/dlang/DIPs/pull/129Thanks for making the DIP. I can't get this code to compile (my struct has an `int i` field): static foreach (i, ref field; src.tupleof) this.tupleof[i] = field; Error: constant value src.i cannot be ref https://run.dlang.io/is/qeugC8 Removing `static` works. Otherwise I tried changing `ref` to `alias`: Error: variable src cannot be read at compile time But this shorter code seems to work fine: this.tupleof = src.tupleof;
Jul 11 2018
On 07/11/2018 05:55 AM, Nick Treleaven wrote:On Tuesday, 10 July 2018 at 10:47:04 UTC, RazvanN wrote:Odd. Timon, what would be the reason for that error? Razvan, can you please look into removing "static" for now. Thanks![1] https://github.com/dlang/DIPs/pull/129Thanks for making the DIP. I can't get this code to compile (my struct has an `int i` field): static foreach (i, ref field; src.tupleof) this.tupleof[i] = field; Error: constant value src.i cannot be ref https://run.dlang.io/is/qeugC8 Removing `static` works. Otherwise I tried changing `ref` to `alias`: Error: variable src cannot be read at compile time But this shorter code seems to work fine: this.tupleof = src.tupleof;
Jul 12 2018
On 12.07.2018 15:29, Andrei Alexandrescu wrote:On 07/11/2018 05:55 AM, Nick Treleaven wrote:The reason for this specific error is that `src.i` is neither a symbol nor a constant value. tupleof is a case of built-in compiler magic, because it can produce an expression tuple that contains run-time values that are not symbols. The following (manually unrolled) code also does not work: alias field0 = s.tupleof[0]; t.tupleof[0] = field0; alias field1 = s.tupleof[1]; t.tupleof[1] = field1; alias field2 = s.tupleof[2]; t.tupleof[2] = field2; Error: alias `a` cannot alias an expression `tuple(s.a, s.b, s.c)[0]` Error: alias `b` cannot alias an expression `tuple(s.a, s.b, s.c)[1]` Error: alias `c` cannot alias an expression `tuple(s.a, s.b, s.c)[2]` It could be argued that the `static foreach` implementation should produce the same error message. (The fact that the AliasDecl constructor takes a Dsymbol instead of an Expression has led to multiple reimplementations of parts of the aliasing logic in different parts of the DMD code, `static foreach` is using the same implementation also used by unrolled foreach, and it requires that all loop variables are either symbols or constant values, while unrolled foreach can fall back to introducing runtime variables for this special case.) One way to fix is to lift all the unnecessary limitations that are introduced by the fact that the AliasDecl constructor takes a Dsymbol. I.e. that "you can only alias symbols". Alternatively, it would be possible to redefine `static foreach` statements such that they work for any aggregate with statically known length and element types, and to allow run-time loop variables to be generated when iterating over run-time values.... Removing `static` works. Otherwise I tried changing `ref` to `alias`: Error: variable src cannot be read at compile time But this shorter code seems to work fine: this.tupleof = src.tupleof;Odd. Timon, what would be the reason for that error? Razvan, can you please look into removing "static" for now. Thanks!
Jul 12 2018
On 12.07.2018 17:22, Timon Gehr wrote:alias field0 = s.tupleof[0]; t.tupleof[0] = field0; alias field1 = s.tupleof[1]; t.tupleof[1] = field1; alias field2 = s.tupleof[2]; t.tupleof[2] = field2; Error: alias `a` cannot alias an expression `tuple(s.a, s.b, s.c)[0]` Error: alias `b` cannot alias an expression `tuple(s.a, s.b, s.c)[1]` Error: alias `c` cannot alias an expression `tuple(s.a, s.b, s.c)[2]`The error messages are actually: Error: alias `field0` cannot alias an expression `tuple(s.a, s.b, s.c)[0]` Error: alias `field1` cannot alias an expression `tuple(s.a, s.b, s.c)[1]` Error: alias `field2` cannot alias an expression `tuple(s.a, s.b, s.c)[2]`
Jul 12 2018
On 07/12/2018 11:22 AM, Timon Gehr wrote:On 12.07.2018 15:29, Andrei Alexandrescu wrote:Thanks!On 07/11/2018 05:55 AM, Nick Treleaven wrote:The reason for this specific error is that `src.i` is neither a symbol nor a constant value. tupleof is a case of built-in compiler magic, because it can produce an expression tuple that contains run-time values that are not symbols. The following (manually unrolled) code also does not work: alias field0 = s.tupleof[0]; t.tupleof[0] = field0; alias field1 = s.tupleof[1]; t.tupleof[1] = field1; alias field2 = s.tupleof[2]; t.tupleof[2] = field2; Error: alias `a` cannot alias an expression `tuple(s.a, s.b, s.c)[0]` Error: alias `b` cannot alias an expression `tuple(s.a, s.b, s.c)[1]` Error: alias `c` cannot alias an expression `tuple(s.a, s.b, s.c)[2]` It could be argued that the `static foreach` implementation should produce the same error message. (The fact that the AliasDecl constructor takes a Dsymbol instead of an Expression has led to multiple reimplementations of parts of the aliasing logic in different parts of the DMD code, `static foreach` is using the same implementation also used by unrolled foreach, and it requires that all loop variables are either symbols or constant values, while unrolled foreach can fall back to introducing runtime variables for this special case.) One way to fix is to lift all the unnecessary limitations that are introduced by the fact that the AliasDecl constructor takes a Dsymbol. I.e. that "you can only alias symbols". Alternatively, it would be possible to redefine `static foreach` statements such that they work for any aggregate with statically known length and element types, and to allow run-time loop variables to be generated when iterating over run-time values.... Removing `static` works. Otherwise I tried changing `ref` to `alias`: Error: variable src cannot be read at compile time But this shorter code seems to work fine: this.tupleof = src.tupleof;Odd. Timon, what would be the reason for that error? Razvan, can you please look into removing "static" for now. Thanks!
Jul 12 2018
On Tuesday, 10 July 2018 at 10:47:04 UTC, RazvanN wrote:I managed to put together a first draft of the DIP for adding the copy constructor to the language [1]. If anyone is interested, please take a look. Suggestions and comments about technical aspects and wording are all welcome.When designing D libraries than lean towards DSL style, I've frequently felt impaired by the lack of implicit conversions in D. In my experience, it's not that all types need to be implicitly convertible to other types. Just being able to mark a few types as implicitly convertible to some other specific types would go a long way to alleviate the limitations I felt. It would also solve problems like an arbitrary limit on the depth of implicit conversions. I had imagined that maybe one day an implicit keyword could be introduced to mark such permissible implicit conversions. Seeing an implicit "keyword" being introduced here with different semantics than I envisioned makes me even less hopeful that some day such implicit conversions annotations could be introduced. So... maybe consider choosing some other syntactic notation? Besides, the fact that the compiler can implicitly introduce calls to the copy ctor doesn't strike me as something particularly central to the concept, so it seems like an odd choice for something to distinguish a copy ctor.
Jul 12 2018
On Thursday, 12 July 2018 at 14:56:33 UTC, Luís Marques wrote:When designing D libraries than lean towards DSL style, I've frequently felt impaired by the lack of implicit conversions in D. In my experience, it's not that all types need to be implicitly convertible to other types. Just being able to mark a few types as implicitly convertible to some other specific types would go a long way to alleviate the limitations I felt. It would also solve problems like an arbitrary limit on the depth of implicit conversions. I had imagined that maybe one day an implicit keyword could be introduced to mark such permissible implicit conversions. Seeing an implicit "keyword" being introduced here with different semantics than I envisioned makes me even less hopeful that some day such implicit conversions annotations could be introduced. So... maybe consider choosing some other syntactic notation? Besides, the fact that the compiler can implicitly introduce calls to the copy ctor doesn't strike me as something particularly central to the concept, so it seems like an odd choice for something to distinguish a copy ctor.More details. The DIP says: "The structName type needs to be identical to typeof(this); an error is issued otherwise. This requirement may be relaxed in the future in order to accomodate copying from objects of a different type" (BTW, typo in "accomodate") That would mean that if such a relaxation were introduced, then suddenly *all* copy ctors would imply implicit conversion between the respective types. Given D's stance on implicit conversions, I suspect that's not going to pass mustard. So I would prefer the any "implicit" keyword-like annotation to be reserved for explicitly approved implicit conversions.
Jul 12 2018
On Thursday, 12 July 2018 at 15:14:19 UTC, Luís Marques wrote:More details. The DIP says: "The structName type needs to be identical to typeof(this); an error is issued otherwise. This requirement may be relaxed in the future in order to accomodate copying from objects of a different type" (BTW, typo in "accomodate") That would mean that if such a relaxation were introduced, then suddenly *all* copy ctors would imply implicit conversion between the respective types. Given D's stance on implicit conversions, I suspect that's not going to pass mustard. So I would prefer the any "implicit" keyword-like annotation to be reserved for explicitly approved implicit conversions.BTW: Multiple alias this is still planned for inclusion in D, right? If so, what would be the (pratical?) difference between having copy ctors with such a relaxed type requirement and just defining an equivalent alias this method? In case the answer is that there's no significant difference, why not drop multiple alias this, then?
Jul 12 2018
On Thursday, 12 July 2018 at 15:25:10 UTC, Luís Marques wrote:On Thursday, 12 July 2018 at 15:14:19 UTC, Luís Marques wrote: BTW: Multiple alias this is still planned for inclusion in D, right? If so, what would be the (pratical?) difference between having copy ctors with such a relaxed type requirement and just defining an equivalent alias this method? In case the answer is that there's no significant difference, why not drop multiple alias this, then?Sorry for the stream-of-conscience type posts. But, to clarify further: if alias this provides access to the members of the converted type (besides type conversion), couldn't that feature be folded into the same mechanism of the copy ctor (or vice-versa), to avoid mostly redundant features in the language, with subtle interactions?
Jul 12 2018
On 07/12/2018 11:29 AM, Luís Marques wrote:On Thursday, 12 July 2018 at 15:25:10 UTC, Luís Marques wrote:The DIP mentions the interaction of implicit with alias this.On Thursday, 12 July 2018 at 15:14:19 UTC, Luís Marques wrote: BTW: Multiple alias this is still planned for inclusion in D, right? If so, what would be the (pratical?) difference between having copy ctors with such a relaxed type requirement and just defining an equivalent alias this method? In case the answer is that there's no significant difference, why not drop multiple alias this, then?Sorry for the stream-of-conscience type posts. But, to clarify further: if alias this provides access to the members of the converted type (besides type conversion), couldn't that feature be folded into the same mechanism of the copy ctor (or vice-versa), to avoid mostly redundant features in the language, with subtle interactions?
Jul 12 2018
On Thursday, 12 July 2018 at 15:34:25 UTC, Andrei Alexandrescu wrote:The DIP mentions the interaction of implicit with alias this.Not the interaction I was asking about, although admittedly it was speculative.
Jul 12 2018
On 07/12/2018 11:25 AM, Luís Marques wrote:On Thursday, 12 July 2018 at 15:14:19 UTC, Luís Marques wrote:Again: not the charter of this DIP, so you should ask yourself, not us, this question.More details. The DIP says: "The structName type needs to be identical to typeof(this); an error is issued otherwise. This requirement may be relaxed in the future in order to accomodate copying from objects of a different type" (BTW, typo in "accomodate") That would mean that if such a relaxation were introduced, then suddenly *all* copy ctors would imply implicit conversion between the respective types. Given D's stance on implicit conversions, I suspect that's not going to pass mustard. So I would prefer the any "implicit" keyword-like annotation to be reserved for explicitly approved implicit conversions.BTW: Multiple alias this is still planned for inclusion in D, right? If so, what would be the (pratical?) difference between having copy ctors with such a relaxed type requirement and just defining an equivalent alias this method? In case the answer is that there's no significant difference, why not drop multiple alias this, then?
Jul 12 2018
On Thursday, 12 July 2018 at 15:33:03 UTC, Andrei Alexandrescu wrote:Again: not the charter of this DIP, so you should ask yourself, not us, this question.Look, I understand it can be frustrating to have a concrete design proposal derailed by a myriad of speculative questions. But if we suspect that design decision of a DIP might interact poorly with other plausible future D features, should we not at least express our concerns and hopes? By the time the other DIPs come out it might be too late to address the concerns. In any case, I hope my comments were not too out of bounds of the discussion. If so, I'm sorry.
Jul 12 2018
On Thursday, 12 July 2018 at 15:42:29 UTC, Luís Marques wrote:On Thursday, 12 July 2018 at 15:33:03 UTC, Andrei Alexandrescu wrote:I like the idea of implicit conversions (until I've been convinced otherwise at least), but I don't necessarily think this DIP will interact poorly with it. They could be implemented with a new opImplicitCast. Less elegantly, you could have special behavior when implicit is used with opCast.Again: not the charter of this DIP, so you should ask yourself, not us, this question.Look, I understand it can be frustrating to have a concrete design proposal derailed by a myriad of speculative questions. But if we suspect that design decision of a DIP might interact poorly with other plausible future D features, should we not at least express our concerns and hopes? By the time the other DIPs come out it might be too late to address the concerns. In any case, I hope my comments were not too out of bounds of the discussion. If so, I'm sorry.
Jul 12 2018
On 7/12/18 11:42 AM, Luís Marques wrote:On Thursday, 12 July 2018 at 15:33:03 UTC, Andrei Alexandrescu wrote:Definitely good topics to discuss. This is a collaborative process, not a confrontational one. If this DIP precludes good future decisions, that's definitely a meaningful discussion.Again: not the charter of this DIP, so you should ask yourself, not us, this question.Look, I understand it can be frustrating to have a concrete design proposal derailed by a myriad of speculative questions. But if we suspect that design decision of a DIP might interact poorly with other plausible future D features, should we not at least express our concerns and hopes? By the time the other DIPs come out it might be too late to address the concerns. In any case, I hope my comments were not too out of bounds of the discussion. If so, I'm sorry.
Jul 12 2018
On Thu, 12 Jul 2018 at 08:30, Luís Marques via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Thursday, 12 July 2018 at 15:14:19 UTC, Luís Marques wrote:implicit constructors state what types an object may *accept*. alias this specifies what types an object may *provide*. They're both about implicit conversion, but specified at either the providing or receiving end. I think they both have reason to exist; they're complementary. It depends if you're authoring an API, or writing a tool to interact with an existing API which is appropriate to use.More details. The DIP says: "The structName type needs to be identical to typeof(this); an error is issued otherwise. This requirement may be relaxed in the future in order to accomodate copying from objects of a different type" (BTW, typo in "accomodate") That would mean that if such a relaxation were introduced, then suddenly *all* copy ctors would imply implicit conversion between the respective types. Given D's stance on implicit conversions, I suspect that's not going to pass mustard. So I would prefer the any "implicit" keyword-like annotation to be reserved for explicitly approved implicit conversions.BTW: Multiple alias this is still planned for inclusion in D, right? If so, what would be the (pratical?) difference between having copy ctors with such a relaxed type requirement and just defining an equivalent alias this method? In case the answer is that there's no significant difference, why not drop multiple alias this, then?
Jul 12 2018
On 07/12/2018 11:14 AM, Luís Marques wrote:On Thursday, 12 July 2018 at 14:56:33 UTC, Luís Marques wrote:No, only constructors annotated with implicit would be implicit. But that's only a possible future direction not part of this DIP. Also there are many complications related to allowing implicit conversions across distinct types, and this DIP should not get embroiled in those. That would be a different pursuit that I encourage you to consider.When designing D libraries than lean towards DSL style, I've frequently felt impaired by the lack of implicit conversions in D. In my experience, it's not that all types need to be implicitly convertible to other types. Just being able to mark a few types as implicitly convertible to some other specific types would go a long way to alleviate the limitations I felt. It would also solve problems like an arbitrary limit on the depth of implicit conversions. I had imagined that maybe one day an implicit keyword could be introduced to mark such permissible implicit conversions. Seeing an implicit "keyword" being introduced here with different semantics than I envisioned makes me even less hopeful that some day such implicit conversions annotations could be introduced. So... maybe consider choosing some other syntactic notation? Besides, the fact that the compiler can implicitly introduce calls to the copy ctor doesn't strike me as something particularly central to the concept, so it seems like an odd choice for something to distinguish a copy ctor.More details. The DIP says: "The structName type needs to be identical to typeof(this); an error is issued otherwise. This requirement may be relaxed in the future in order to accomodate copying from objects of a different type" (BTW, typo in "accomodate") That would mean that if such a relaxation were introduced, then suddenly *all* copy ctors would imply implicit conversion between the respective types.
Jul 12 2018
On Thu, 12 Jul 2018 at 08:36, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 07/12/2018 11:14 AM, Luís Marques wrote:I feel like this DIP depends on an implicit DIP, and that one needs to come first...On Thursday, 12 July 2018 at 14:56:33 UTC, Luís Marques wrote:No, only constructors annotated with implicit would be implicit. But that's only a possible future direction not part of this DIP. Also there are many complications related to allowing implicit conversions across distinct types, and this DIP should not get embroiled in those. That would be a different pursuit that I encourage you to consider.When designing D libraries than lean towards DSL style, I've frequently felt impaired by the lack of implicit conversions in D. In my experience, it's not that all types need to be implicitly convertible to other types. Just being able to mark a few types as implicitly convertible to some other specific types would go a long way to alleviate the limitations I felt. It would also solve problems like an arbitrary limit on the depth of implicit conversions. I had imagined that maybe one day an implicit keyword could be introduced to mark such permissible implicit conversions. Seeing an implicit "keyword" being introduced here with different semantics than I envisioned makes me even less hopeful that some day such implicit conversions annotations could be introduced. So... maybe consider choosing some other syntactic notation? Besides, the fact that the compiler can implicitly introduce calls to the copy ctor doesn't strike me as something particularly central to the concept, so it seems like an odd choice for something to distinguish a copy ctor.More details. The DIP says: "The structName type needs to be identical to typeof(this); an error is issued otherwise. This requirement may be relaxed in the future in order to accomodate copying from objects of a different type" (BTW, typo in "accomodate") That would mean that if such a relaxation were introduced, then suddenly *all* copy ctors would imply implicit conversion between the respective types.
Jul 12 2018
On 7/12/18 7:15 PM, Manu wrote:On Thu, 12 Jul 2018 at 08:36, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:Negative.On 07/12/2018 11:14 AM, Luís Marques wrote:I feel like this DIP depends on an implicit DIP, and that one needs to come first...On Thursday, 12 July 2018 at 14:56:33 UTC, Luís Marques wrote:No, only constructors annotated with implicit would be implicit. But that's only a possible future direction not part of this DIP. Also there are many complications related to allowing implicit conversions across distinct types, and this DIP should not get embroiled in those. That would be a different pursuit that I encourage you to consider.When designing D libraries than lean towards DSL style, I've frequently felt impaired by the lack of implicit conversions in D. In my experience, it's not that all types need to be implicitly convertible to other types. Just being able to mark a few types as implicitly convertible to some other specific types would go a long way to alleviate the limitations I felt. It would also solve problems like an arbitrary limit on the depth of implicit conversions. I had imagined that maybe one day an implicit keyword could be introduced to mark such permissible implicit conversions. Seeing an implicit "keyword" being introduced here with different semantics than I envisioned makes me even less hopeful that some day such implicit conversions annotations could be introduced. So... maybe consider choosing some other syntactic notation? Besides, the fact that the compiler can implicitly introduce calls to the copy ctor doesn't strike me as something particularly central to the concept, so it seems like an odd choice for something to distinguish a copy ctor.More details. The DIP says: "The structName type needs to be identical to typeof(this); an error is issued otherwise. This requirement may be relaxed in the future in order to accomodate copying from objects of a different type" (BTW, typo in "accomodate") That would mean that if such a relaxation were introduced, then suddenly *all* copy ctors would imply implicit conversion between the respective types.
Jul 12 2018
On Thu., 12 Jul. 2018, 7:10 pm Andrei Alexandrescu via Digitalmars-d, < digitalmars-d puremagic.com> wrote:On 7/12/18 7:15 PM, Manu wrote:nOn Thu, 12 Jul 2018 at 08:36, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 07/12/2018 11:14 AM, Lu=C3=ADs Marques wrote:On Thursday, 12 July 2018 at 14:56:33 UTC, Lu=C3=ADs Marques wrote:When designing D libraries than lean towards DSL style, I've frequently felt impaired by the lack of implicit conversions in D. I=smy experience, it's not that all types need to be implicitly convertible to other types. Just being able to mark a few types as implicitly convertible to some other specific types would go a long way to alleviate the limitations I felt. It would also solve problem=anlike an arbitrary limit on the depth of implicit conversions. I had imagined that maybe one day an implicit keyword could be introduced to mark such permissible implicit conversions. Seeing an implicit "keyword" being introduced here with different semantics th=isI envisioned makes me even less hopeful that some day such implicit conversions annotations could be introduced. So... maybe consider choosing some other syntactic notation? Besides, the fact that the compiler can implicitly introduce calls to the copy ctor doesn't strike me as something particularly central to the concept, so it seems like an odd choice for something to distinguish a copy ctor.More details. The DIP says: "The structName type needs to be identical to typeof(this); an error =veorderissued otherwise. This requirement may be relaxed in the future insuddenlyto accomodate copying from objects of a different type" (BTW, typo in "accomodate") That would mean that if such a relaxation were introduced, then*all* copy ctors would imply implicit conversion between the respecti=edtypes.No, only constructors annotated with implicit would be implicit. But that's only a possible future direction not part of this DIP. Also there are many complications related to allowing implicit conversions across distinct types, and this DIP should not get embroil=Double-negative.. why would we support introduction of this implicit attribute if it's not proposed how it will work in general? Introducing more attributes is a big deal. For the record, now that I 'get it', I'm super jazzed about having implicit in the language. I've wanted it since day-one! But I don't want to be swindled into accepting its existence prior to being comfortable that the design/intent/implementation is right. We can't get it out if the theoretical future DIP that makes it broadly useful is not agreeable. The potential introduction of implicit makes me about 100x more interested (and critical) of this DIP. Now that it's on the table, I *really* care that this goes right. Seriously, if I was making this proposal to you, and you were in my position... there is no way in hell that you'd allow any of us to slip something so substantial by like that with the wave of a hand. This DIP depends on implicit. How can you argue otherwise?Negative.in those. That would be a different pursuit that I encourage you to consider.I feel like this DIP depends on an implicit DIP, and that one needs to come first...
Jul 12 2018
On Friday, 13 July 2018 at 02:32:59 UTC, Manu wrote:Seriously, if I was making this proposal to you, and you were in my position... there is no way in hell that you'd allow any of us to slip something so substantial by like that with the wave of a hand. This DIP depends on implicit. How can you argue otherwise?Nothing is being slipped by as far as I'm concerned. implicit is solely introduced in the DIP as a marker for the copy constructor, and it doesn't seem like it's intended for anything further than avoiding breaking code. It feels to me like you're making a mountain out of an ant hill. Still, regardless of what the intention was, implicit was a poor choice of words for exactly this reason. The DIP itself seems solid. Makes me a little nervous to be introducing copy constructors, but if it's really that untenable to typecheck qualified postblits, then I'm all for it. One step closer to eliminating Qualified Hell when wrapping structs in other structs.
Jul 12 2018
On Thu, 12 Jul 2018 at 20:15, Meta via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Friday, 13 July 2018 at 02:32:59 UTC, Manu wrote:That's the whole point though. We're debating whether " implicit" is a good idea. And it's the only detail of the DIP that feels noteworthy or contentious to me. The rest is pretty much common-sense, and long overdue. I can see myself getting behind 2 possibilities, no implicit, or implicit done right. I don't see myself getting behind introduction of implicit on such terms that it's nothing but "a marker for the copy constructor". So this 'mountain' is critical to understanding whether I can support this DIP as proposed or not.Seriously, if I was making this proposal to you, and you were in my position... there is no way in hell that you'd allow any of us to slip something so substantial by like that with the wave of a hand. This DIP depends on implicit. How can you argue otherwise?Nothing is being slipped by as far as I'm concerned. implicit is solely introduced in the DIP as a marker for the copy constructor, and it doesn't seem like it's intended for anything further than avoiding breaking code. It feels to me like you're making a mountain out of an ant hill.Still, regardless of what the intention was, implicit was a poor choice of words for exactly this reason.I disagree; it's the perfect choice assuming an " implicit done right" future. And if that's the case, I'll get behind that with all my insignificant weight, but we need to know how it's defined up front. If we're not assuming that, then the conversation goes completely differently, and I would want to resist any such attribute or marker for the time being until we can explore that other future. We can't make a decision about it unless we know where it's destined. Also, this 'ant hill' is _copy construction_, there are few mechanics we could be talking about so fundamentally important and significant to the future of the language. Copy construction is HUGE! This is our one chance to correct some major mistakes from the past, and I'm glad it's being worked on.
Jul 12 2018
On 7/12/18 11:45 PM, Manu wrote:On Thu, 12 Jul 2018 at 20:15, Meta via Digitalmars-d <digitalmars-d puremagic.com> wrote:A couple of simple ideas are making the process productive. One is to rely on facts instead of feelings. "It's weird" or "I don't like it" are less helpful than "semantics of this or that case are not covered". Another is precision. Stating vague goals and standards ("I want implicit done well") and systematically asking others to actually put in the work is less desirable than providing concrete, motivated, actionable feedback. To the second point: we have a history of defining features too permissively, to then regret not having waited to accumulate experience. Starting with a restricted version then building on experience with it seems to be a much better strategy. From that perspective, introducing implicit only for restricted copy construction seems like a good step that doesn't take others, without precluding them.On Friday, 13 July 2018 at 02:32:59 UTC, Manu wrote:That's the whole point though. We're debating whether " implicit" is a good idea. And it's the only detail of the DIP that feels noteworthy or contentious to me. The rest is pretty much common-sense, and long overdue. I can see myself getting behind 2 possibilities, no implicit, or implicit done right.Seriously, if I was making this proposal to you, and you were in my position... there is no way in hell that you'd allow any of us to slip something so substantial by like that with the wave of a hand. This DIP depends on implicit. How can you argue otherwise?Nothing is being slipped by as far as I'm concerned. implicit is solely introduced in the DIP as a marker for the copy constructor, and it doesn't seem like it's intended for anything further than avoiding breaking code. It feels to me like you're making a mountain out of an ant hill.I don't see myself getting behind introduction of implicit on such terms that it's nothing but "a marker for the copy constructor". So this 'mountain' is critical to understanding whether I can support this DIP as proposed or not.I'd put it a slightly different way. "Getting behind" and "supporting or not" suggests a position of power and an emphasis on the politics of the process. The natural counter to this would be asking whether your support is necessary, which put us all in a very unproductive position. The right emphasis is not getting your support on a given DIP, but instead us all benefiting of your active contribution to a better DIP. Thanks, Andrei
Jul 13 2018
On Fri, 13 Jul 2018 at 07:35, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 7/12/18 11:45 PM, Manu wrote:What "I don't like" is using an attribute as a marker, and especially in the unique case of a copy constructor, which is so fundamental to the language. If it has a systemic meaning, as it's sort-of proposed that maybe it might in the future sometime, then it's fine. There's a lot of subjectivity in programming. I don't like that python has significant white-space. I don't like that Javascript isn't a native language. I don't like the idea of introducing an attribute as a marker in a single case, without some expectation that it has a future beyond that.I can see myself getting behind 2 possibilities, no implicit, or implicit done right.A couple of simple ideas are making the process productive. One is to rely on facts instead of feelings. "It's weird" or "I don't like it" are less helpful than "semantics of this or that case are not covered".Another is precision. Stating vague goals and standards ("I want implicit done well") and systematically asking others to actually put in the work is less desirable than providing concrete, motivated, actionable feedback.As I originally said, my feedback is concrete: specify implicit, this DIP depends on it. My language like " implicit done right" came later, as a reference to prior comments. As I've said, I actually really want implicit, but I want to be satisfied by it's definition and somewhat convinced that it has a future, and specifically, that it's NOT just a marker to be used in this case. It's not about 'asking others to put in the work', this DIP has a dependency on it, so it can't not be defined. The definition is currently "it's a marker, and maybe we might do something in the future", and that's a poor definition. If I presented a DIP which casually dropped in a new attribute, you would absolutely insist that I specify it.To the second point: we have a history of defining features too permissively, to then regret not having waited to accumulate experience. Starting with a restricted version then building on experience with it seems to be a much better strategy. From that perspective, introducing implicit only for restricted copy construction seems like a good step that doesn't take others, without precluding them.There's also property... and 'scope' as existed prior DIP1000, and 'in'. I think this thing needs at least a little spec-ing. If it's clear up front that it's not going anywhere (easily shot-down or whatever), then it's not a good choice. If it looks generally promising for the future, and there's no obvious roadblocks for wider deployment, then we're good, and I'll desist on this point. I don't know how we can be confident of that without at least a little exploration.Presenting a proposal to the community is an implicit request for support. I'm not saying I have any power further than my reading of the proposal and sharing my own judgement of its merit. You can do whatever you do... I'm just saying what I find satisfying, and this proposal is not satisfying without some further substantiation of the proposed new attribute.I don't see myself getting behind introduction of implicit on such terms that it's nothing but "a marker for the copy constructor". So this 'mountain' is critical to understanding whether I can support this DIP as proposed or not.I'd put it a slightly different way. "Getting behind" and "supporting or not" suggests a position of power and an emphasis on the politics of the process. The natural counter to this would be asking whether your support is necessary, which put us all in a very unproductive position.The right emphasis is not getting your support on a given DIP, but instead us all benefiting of your active contribution to a better DIP.I've already contributed other points to this DIP in the way you describe. This one however is very strange, and I'm surprised you can find the hand-wavy introduction of a new attribute without any sense of where it's going to be okay. Or maybe, I'm surprised I'm the only one that finds problem with that. My feeling is inspired by ' property', 'scope', 'in'. We don't need any more events like those.
Jul 13 2018
On 14/07/2018 9:28 AM, Manu wrote:I've already contributed other points to this DIP in the way you describe. This one however is very strange, and I'm surprised you can find the hand-wavy introduction of a new attribute without any sense of where it's going to be okay. Or maybe, I'm surprised I'm the only one that finds problem with that.You are very much not alone. I didn't articulate it very clearly, but I am super not happy with such a new attribute.
Jul 13 2018
On Friday, 13 July 2018 at 21:49:57 UTC, rikki cattermole wrote:On 14/07/2018 9:28 AM, Manu wrote:I'm not crazy about it either, but it may be a necessary evil to avoid breaking code (although it doesn't entirely avoid that, as has been demonstrated).I've already contributed other points to this DIP in the way you describe. This one however is very strange, and I'm surprised you can find the hand-wavy introduction of a new attribute without any sense of where it's going to be okay. Or maybe, I'm surprised I'm the only one that finds problem with that.You are very much not alone. I didn't articulate it very clearly, but I am super not happy with such a new attribute.
Jul 13 2018
On 7/13/18 5:49 PM, rikki cattermole wrote:On 14/07/2018 9:28 AM, Manu wrote:It's a very simple process - implicit is not invented as much as a given. We need to distinguish a constructor from other constructors. The constructor supports attributes. Attributes are a mechanism for distinguishing declarations from other declarations. Ergo, an attribute is the mechanism of choice. Done deal. ===== If we don't like the use of an attribute, it means we somehow failed in defining attributes in the first place. (I don't think we did; attributes as defined in D are brilliant and currently underused.) It's poor language design to define a mechanism for doing a category of Xs and then explicitly avoiding it exactly when the opportunity of doing X arises. From that vantage point, the choice of an attribute to identify implicit copy construction is unassailably obvious, and elucubrated syntax inventions such as " this", "this(ref this x)" are chucklesomely profligate and ridiculously baroque. AndreiI've already contributed other points to this DIP in the way you describe. This one however is very strange, and I'm surprised you can find the hand-wavy introduction of a new attribute without any sense of where it's going to be okay. Or maybe, I'm surprised I'm the only one that finds problem with that.You are very much not alone. I didn't articulate it very clearly, but I am super not happy with such a new attribute.
Jul 13 2018
On Fri, 13 Jul 2018 at 18:00, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 7/13/18 5:49 PM, rikki cattermole wrote:But you surely recognise that D has a lot of intrinsic attributes already, and that's a lot of mental (and visual) baggage to carry around. If we add a new intrinsic attribute, I would want to be sure it's widely useful, because every D user will need to learn about and understand it. It's much easier to learn, and more useful knowledge to have, if it has a broad meaning which solves a general class of problem, than just a marker that you need to remember you have to type in one specific niche location.On 14/07/2018 9:28 AM, Manu wrote:It's a very simple process - implicit is not invented as much as a given. We need to distinguish a constructor from other constructors. The constructor supports attributes. Attributes are a mechanism for distinguishing declarations from other declarations. Ergo, an attribute is the mechanism of choice. Done deal. ===== If we don't like the use of an attribute, it means we somehow failed in defining attributes in the first place. (I don't think we did; attributes as defined in D are brilliant and currently underused.) It's poor language design to define a mechanism for doing a category of Xs and then explicitly avoiding it exactly when the opportunity of doing X arises. From that vantage point, the choice of an attribute to identify implicit copy construction is unassailably obvious, and elucubrated syntax inventions such as " this", "this(ref this x)" are chucklesomely profligate and ridiculously baroque.I've already contributed other points to this DIP in the way you describe. This one however is very strange, and I'm surprised you can find the hand-wavy introduction of a new attribute without any sense of where it's going to be okay. Or maybe, I'm surprised I'm the only one that finds problem with that.You are very much not alone. I didn't articulate it very clearly, but I am super not happy with such a new attribute.
Jul 13 2018
On Saturday, 14 July 2018 at 00:57:14 UTC, Andrei Alexandrescu wrote:[...] chucklesomely profligate and ridiculously baroque. AndreiHahaha this sentence... amazing! :D I was going to propose auto this(ref A other) {} but nevermind :p Cheers, - Ali
Jul 17 2018
On 7/13/18 5:28 PM, Manu wrote:As I originally said, my feedback is concrete: specify implicit, this DIP depends on it.The specification of implicit is in the DIP in full: a constructor that takes by reference a qualified typeof(this) and has the implicit attribute will be callable implicitly by the compiler. There is no other meaning of implicit. That completes the spec of implicit. Sadly we got to irreducible positions once again: you and I used different definitions for common terms like "define", "specify", "explain", "contribute", and then you use them to ask questions or make demands, all of which I'm sure you find reasonable. But I am unable to understand them, let alone take them under advisement when working on the DIP. (I did understand your reference to the assignment and will work on that, thanks much.) You will need to forgive me for the scarcity of my future answers - but believe me I will do my best to derive value from your feedback. Andrei
Jul 13 2018
On Fri, 13 Jul 2018 at 17:45, Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 7/13/18 5:28 PM, Manu wrote:Right, and this is 100% of my concern here. To introduce a new attribute for such a one-off purpose feels like a poor choice, and on those terms I would rather see the feature work with no such attribute (as we've considered in the other fork). If you assess the likelihood of actually breaking code in the wild (I expect it's super slim; data would be nice), you might find that the risk is satisfactory. However, the DIP alludes to a possible future for the attribute, and I think that text is intended to make us feel better about the introduction of the attribute, but I would be a lot more comfortable with a more substantial support of its introduction. Basically, and you already know this; I think it's a weird choice to introduce a new attribute for this one-off case, but as a systemic feature which addresses a general long-standing problem, it feels like a good and logical solution. I think we need some idea if the broader application is even theoretically workable up-front. If there's obvious issues with the idea of deploying implicit generally, then we shouldn't deploy it here, and instead, we should deploy something else here which CAN successfully be generalised in the future. Determining that requires at least a cursory exploration.As I originally said, my feedback is concrete: specify implicit, this DIP depends on it.The specification of implicit is in the DIP in full: a constructor that takes by reference a qualified typeof(this) and has the implicit attribute will be callable implicitly by the compiler. There is no other meaning of implicit. That completes the spec of implicit.
Jul 13 2018
On 14/07/2018 1:04 PM, Manu wrote:Determining that requires at least a cursory exploration.Given how many of us are objecting to the syntax, I'm going to place this requirement upon a 'yes' answer by me. That an attempt is made for an alternative syntax discussion. It's a fair request I think.
Jul 14 2018
On Sat., 14 Jul. 2018, 2:00 am rikki cattermole via Digitalmars-d, < digitalmars-d puremagic.com> wrote:On 14/07/2018 1:04 PM, Manu wrote:I just want to reiterate again, I'm not seeking alternative syntax, I just want to know that proposed syntax can work broadly, or if there are any challenges or problems that would restrict it from broad application.Determining that requires at least a cursory exploration.Given how many of us are objecting to the syntax, I'm going to place this requirement upon a 'yes' answer by me. That an attempt is made for an alternative syntax discussion. It's a fair request I think.
Jul 14 2018
On Saturday, 14 July 2018 at 00:41:37 UTC, Andrei Alexandrescu wrote:The specification of implicit is in the DIP in full: a constructor that takes by reference a qualified typeof(this) and has the implicit attribute will be callable implicitly by the compiler. There is no other meaning of implicit. That completes the spec of implicit.That is the problem: you are using a very generic name ("implicit") to signify both: 1) something very general ("will be callable implicitly by the compiler") and 2) something very specific ("a constructor that takes by reference a qualified typeof(this)") If there is "no other meaning of implicit" (other than the intersection of those two properties) why don't you just call it something like copyctor? On the other hand, if the name is chosen with the hope that the meaning will be generalized in the future ("callable implicitly by the compiler"), why don't you want to at least briefly discuss that more general meaning? What happens if you later conclude that a generic "callable implicitly by the compiler" annotation has semantics that don't quite align with those of this ctor annotation? Do you need to introduce implicitconv? Surely we want the language constructs to be composable and generalizable, and not just quirky one offs that you have to memorize. This seems like a missed opportunity to make sure of that.
Jul 14 2018
On 7/14/18 5:03 AM, Luís Marques wrote:If there is "no other meaning of implicit" (other than the intersection of those two properties) why don't you just call it something like copyctor?I'm totally cool with giving the attribute a more obscure name such as copyctor or anything people want really. (What follows is a personal opinion. I think it's better to choose a more general attribute name with reduced initial applicability. Then application of said attribute can be extended to other functions with ease. In contrast, an obscure attribute name is sure to be followed by more obscure attribute names. And don't get me started about inventing new syntax. Regarding the hand-wringing over generality: we have an exceedingly poor record of paralysis of analysis, whereby we'd worry that every design decision potentially locks us out from all other as-of-yet-unchosen design decisions. If history is any indication, this sudden worry about vaguely-promising green pastures of the future is a sign of malady. We want copy construction. Conflating this with a very general schemata for implicit conversion would not be a wise decision in my opinion. I now deeply regret ever telling Razvan to mention future possible directions. This DIP must do implicit copy constructors and do it well, nothing less and nothing more.) Andrei
Jul 14 2018
On Saturday, 14 July 2018 at 10:53:17 UTC, Andrei Alexandrescu wrote:I now deeply regret ever telling Razvan to mention future possible directions. This DIP must do implicit copy constructors and do it well, nothing less and nothing more.Strongly agree with this. In my review on Github I had a few sentences about this, but I removed them because I thought it may be perceived wrong. I find it almost completely irrelevant to add a "future directions" discussion to a DIP. If a DIP is incomplete, then finish it. Other than that, a DIP should stand completely on its own, regardless of speculation on future directions. -Johan
Jul 14 2018
On 14/07/2018 11:49 PM, Johan Engelen wrote:On Saturday, 14 July 2018 at 10:53:17 UTC, Andrei Alexandrescu wrote:Really any mention of the "future" in a DIP section wise, should be fairly concrete. I.e. this is already a good design, BUT it may come to pass that this use case is indeed important to support (an acknowledgement to its existence) so here is an idea on how to support it. It doesn't need to be entirely thought out, it just needs to be pretty well thought out and with clear added complexity as to why it isn't part of the original DIP. The example I'll use is my named arguments DIP[0], where I show a feature that could be added to allow renaming of args. However, because I'm unconvinced that such a complex feature is even needed, I don't support it. [0] https://github.com/rikkimax/DIPs/blob/named_args/DIPs/DIP1xxx-RC.md#future-proposalsI now deeply regret ever telling Razvan to mention future possible directions. This DIP must do implicit copy constructors and do it well, nothing less and nothing more.Strongly agree with this. In my review on Github I had a few sentences about this, but I removed them because I thought it may be perceived wrong. I find it almost completely irrelevant to add a "future directions" discussion to a DIP. If a DIP is incomplete, then finish it. Other than that, a DIP should stand completely on its own, regardless of speculation on future directions. -Johan
Jul 14 2018
On Saturday, 14 July 2018 at 10:53:17 UTC, Andrei Alexandrescu wrote:On 7/14/18 5:03 AM, Luís Marques wrote:I think in this case, a more obscure name like copyctor is more descriptive. I fear that at some point, a more general attribute like " implicit" will turn into the next "static". To me, implicit smells like one of those keywords that will grow to carry many different meanings in different contexts and just end up overly-broad. -JonIf there is "no other meaning of implicit" (other than the intersection of those two properties) why don't you just call it something like copyctor?I'm totally cool with giving the attribute a more obscure name such as copyctor or anything people want really. (What follows is a personal opinion. I think it's better to choose a more general attribute name with reduced initial applicability. Then application of said attribute can be extended to other functions with ease. In contrast, an obscure attribute name is sure to be followed by more obscure attribute names. And don't get me started about inventing new syntax. Regarding the hand-wringing over generality: we have an exceedingly poor record of paralysis of analysis, whereby we'd worry that every design decision potentially locks us out from all other as-of-yet-unchosen design decisions. If history is any indication, this sudden worry about vaguely-promising green pastures of the future is a sign of malady. We want copy construction. Conflating this with a very general schemata for implicit conversion would not be a wise decision in my opinion. I now deeply regret ever telling Razvan to mention future possible directions. This DIP must do implicit copy constructors and do it well, nothing less and nothing more.) Andrei
Jul 16 2018
On Mon., 16 Jul. 2018, 6:00 pm docandrew via Digitalmars-d, < digitalmars-d puremagic.com> wrote:On Saturday, 14 July 2018 at 10:53:17 UTC, Andrei Alexandrescu wrote:But that's the point, and the key advantage of the name ;)On 7/14/18 5:03 AM, Lu=C3=ADs Marques wrote:I think in this case, a more obscure name like copyctor is more descriptive. I fear that at some point, a more general attribute like " implicit" will turn into the next "static". To me, implicit smells like one of those keywords that will grow to carry many different meanings in different contexts and just end up overly-broad.If there is "no other meaning of implicit" (other than the intersection of those two properties) why don't you just call it something like copyctor?I'm totally cool with giving the attribute a more obscure name such as copyctor or anything people want really. (What follows is a personal opinion. I think it's better to choose a more general attribute name with reduced initial applicability. Then application of said attribute can be extended to other functions with ease. In contrast, an obscure attribute name is sure to be followed by more obscure attribute names. And don't get me started about inventing new syntax. Regarding the hand-wringing over generality: we have an exceedingly poor record of paralysis of analysis, whereby we'd worry that every design decision potentially locks us out from all other as-of-yet-unchosen design decisions. If history is any indication, this sudden worry about vaguely-promising green pastures of the future is a sign of malady. We want copy construction. Conflating this with a very general schemata for implicit conversion would not be a wise decision in my opinion. I now deeply regret ever telling Razvan to mention future possible directions. This DIP must do implicit copy constructors and do it well, nothing less and nothing more.) Andrei
Jul 16 2018
On 7/17/18 12:04 AM, Manu wrote:But that's the point, and the key advantage of the name ;)[:nod:]
Jul 17 2018
On Tuesday, 17 July 2018 at 04:04:33 UTC, Manu wrote:On Mon., 16 Jul. 2018, 6:00 pm docandrew via Digitalmars-d, < digitalmars-d puremagic.com> wrote:Aye! And in this case it really is implicit copy construction. With this attribute in the compiler I can also see a future DIP that deprecates implicit construction and requires an explicit implicit be added to constructors! Which also sounds like a win :D It's not ideal that the implicit attribute does not have a larger discussion around it. But it is nice to something in D where the default is the conservative approach and the more liberal has to be explicitly asked for. And at the same time, at this point it really is an attribute that is only applicable to copy constructors. So how much expansion on that would be enough I wonder? Cheers, - AliOn Saturday, 14 July 2018 at 10:53:17 UTC, Andrei Alexandrescu wrote:But that's the point, and the key advantage of the name ;)On 7/14/18 5:03 AM, Luís Marques wrote:I think in this case, a more obscure name like copyctor is more descriptive. I fear that at some point, a more general attribute like " implicit" will turn into the next "static". To me, implicit smells like one of those keywords that will grow to carry many different meanings in different contexts and just end up overly-broad.If there is "no other meaning of implicit" (other than the intersection of those two properties) why don't you just call it something like copyctor?I'm totally cool with giving the attribute a more obscure name such as copyctor or anything people want really. (What follows is a personal opinion. I think it's better to choose a more general attribute name with reduced initial applicability. Then application of said attribute can be extended to other functions with ease. In contrast, an obscure attribute name is sure to be followed by more obscure attribute names. And don't get me started about inventing new syntax. Regarding the hand-wringing over generality: we have an exceedingly poor record of paralysis of analysis, whereby we'd worry that every design decision potentially locks us out from all other as-of-yet-unchosen design decisions. If history is any indication, this sudden worry about vaguely-promising green pastures of the future is a sign of malady. We want copy construction. Conflating this with a very general schemata for implicit conversion would not be a wise decision in my opinion. I now deeply regret ever telling Razvan to mention future possible directions. This DIP must do implicit copy constructors and do it well, nothing less and nothing more.) Andrei
Jul 17 2018
On 7/16/18 8:57 PM, docandrew wrote:I think in this case, a more obscure name like copyctor is more descriptive.On the contrary, it is redundant and uninformative. It applies to exactly a constructor that copies, so it adds no information. " implicit" describes precisely what the attribute does.
Jul 17 2018
On Saturday, 14 July 2018 at 10:53:17 UTC, Andrei Alexandrescu wrote:I think it's better to choose a more general attribute name with reduced initial applicability. Then application of said attribute can be extended to other functions with ease. In contrast, an obscure attribute name is sure to be followed by more obscure attribute names. And don't get me started about inventing new syntax. Regarding the hand-wringing over generality: we have an exceedingly poor record of paralysis of analysis, whereby we'd worry that every design decision potentially locks us out from all other as-of-yet-unchosen design decisions. If history is any indication, this sudden worry about vaguely-promising green pastures of the future is a sign of malady. We want copy construction. Conflating this with a very general schemata for implicit conversion would not be a wise decision in my opinion. I now deeply regret ever telling Razvan to mention future possible directions. This DIP must do implicit copy constructors and do it well, nothing less and nothing more.)I also think a more general attribute is better. I think there's a middle ground between total analysis paralysis and no discussion of concept generality. I had hoped some thought would be given to the implications of implicit but overall I'm still happy, and I trust your judgement. BTW, I would still have brought it up even if the DIP didn't mention future directions :-)
Jul 17 2018
On Tue, 10 Jul 2018 at 03:50, RazvanN via Digitalmars-d <digitalmars-d puremagic.com> wrote:Hi everyone! I managed to put together a first draft of the DIP for adding the copy constructor to the language [1]. If anyone is interested, please take a look. Suggestions and comments about technical aspects and wording are all welcome. Thanks, RazvanN [1] https://github.com/dlang/DIPs/pull/129I'd like to see a mention on extern(C++) copy constructors; are they naturally semantically compatible? If not, how will it behave differently when extern(C++) is applied (ie, like C++)? Normal constructors and destructors change semantics in the presence of extern(C++).
Jul 12 2018
From the DIP:The copy constructor declaration will be recognized by the parser when the tokens , implicit, this are encountered exactly in this orderRegarding "exactly in this order". The code below would be allowed and define copy c'tor for `A` and usual c'tor for `B` ? struct implicit{} struct A { safe implicit this(ref A) {} } struct B { implicit safe this(ref B) {} }
Jul 13 2018
On 7/13/18 12:06 PM, xenon325 wrote:From the DIP:We'll change that part to accept the standard attribute syntax.The copy constructor declaration will be recognized by the parser when the tokens , implicit, this are encountered exactly in this orderRegarding "exactly in this order". The code below would be allowed and define copy c'tor for `A` and usual c'tor for `B` ? struct implicit{} struct A { safe implicit this(ref A) {} } struct B { implicit safe this(ref B) {} }
Jul 13 2018