July 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:
>>
>> 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:
>>>> 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.
>>
>> 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.
> 
> I feel like this DIP depends on an @implicit DIP, and that one needs
> to come first...

Negative.

July 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:
> > 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.

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.
July 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:
>>
>> On 07/12/2018 09:49 AM, Atila Neves wrote:
>>> 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
>>
>> 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++.
> 
> As I've said elsewhere, opAssign() can be fabricated by:
>    this.destroy(); emplace(&this, copyFrom);

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.

> We 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
July 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:
>>
>> On 07/11/2018 11:11 AM, Atila Neves wrote:
>>> On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:
>>>>> 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.
>>>
>>> How is this different from other types of constructors or destructors?
>>
>> The main difference is that the compiler may insert calls to it implicitly.
> 
> You mean like ~this(), and op[Anything](), and front() and popFront()
> and empty()?
> I don't think we need this attribute.

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.
July 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:
>>
>> 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.
> 
> 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.

Affirmative. The DIP needs to specify how assignment is handled if no opAssign is present but a copy ctor is present. Thanks!

July 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:
> > 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:
> >>> 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.
> >>
> >> 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.
> >
> > I feel like this DIP depends on an @implicit DIP, and that one needs to come first...
>
> Negative.
>

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?


July 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:
> > 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:
> >>> On Wednesday, 11 July 2018 at 07:40:32 UTC, RazvanN wrote:
> >>>>> 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.
> >>>
> >>> How is this different from other types of constructors or destructors?
> >>
> >> The main difference is that the compiler may insert calls to it implicitly.
> >
> > You mean like ~this(), and op[Anything](), and front() and popFront()
> > and empty()?
> > I don't think we need this attribute.
>
> 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.

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.
July 13, 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.
July 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:
> > 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.

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.

> 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.
July 13, 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:
>>
>> > 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.
>
> Exactly. Is that a problem?
> It probably IS a copy constructor already, what else could it be? :)
>

it can be something else. For example a lifo list pusher. Even if it is considered bad design, someone might have done it