December 10, 2012
On Monday, December 10, 2012 05:12:17 Mehrdad wrote:
> On Monday, 10 December 2012 at 03:53:04 UTC, Walter Bright wrote:
> > I do not dispute that deep copy is commonly used in C++. I challenge the idea that it is a good design pattern, i.e. better than using copy-on-write.
> 
> Ignoring the design issue, it's plain faster -- for COW you have to perform checks on every call.

Well, if you're doing a lot of copying and very little mutating, then COW could end up being much faster if copying is expensive (strings types in C++ would probably be a good example of this). However, if you're doing a lot of mutating, then COW doesn't save you much (if anything) and definitely could end up costing you more with all of the extra checks. It all depends on the use case. Regardless, I think that the decision should be made by the programmer. If we want to do things to encourage better idioms or make them easier, then fine, but I don't think that it makes sense to get rid of being able to deep copy structs via a postblit or copy constructor. If anything, I think that  we need to _add_ copy constructors so that we can get around the impossibility of a const or immutable postblit.

- Jonathan M Davis
December 10, 2012
On Monday, 10 December 2012 at 03:53:04 UTC, Walter Bright wrote:
> On 12/9/2012 2:10 PM, Jonathan M Davis wrote:
>> You're basically suggesting that we disallow any idiom which requires that
>> structs be deep copied, and I think that that's bad policy. It's one thing to
>> encourage programmers to not write such structs and to use other idioms like
>> COW or reference counting. It's another thing entirely to disallow them. It's
>> one of C++'s prime tenets to try and not force the programmer to program in a
>> certain way or in a certain paradigm, and I think that D should do the same.
>
> We already disallow several C++ idioms - like multiple inheritance, using a type as both a value and a reference type, and head const. We believe that these are bad design patterns, despite them being used often in C++.
>

D didn't removed them, it replaced it with better idioms, that still allow the valid uses and make bogus uses less likely.

Here we are talking to remove a possibility, without providing something better.
December 10, 2012
On 12/9/2012 11:06 PM, deadalnix wrote:
> On Monday, 10 December 2012 at 03:53:04 UTC, Walter Bright wrote:
>> On 12/9/2012 2:10 PM, Jonathan M Davis wrote:
>>> You're basically suggesting that we disallow any idiom which requires that
>>> structs be deep copied, and I think that that's bad policy. It's one thing to
>>> encourage programmers to not write such structs and to use other idioms like
>>> COW or reference counting. It's another thing entirely to disallow them. It's
>>> one of C++'s prime tenets to try and not force the programmer to program in a
>>> certain way or in a certain paradigm, and I think that D should do the same.
>>
>> We already disallow several C++ idioms - like multiple inheritance, using a
>> type as both a value and a reference type, and head const. We believe that
>> these are bad design patterns, despite them being used often in C++.
>>
>
> D didn't removed them, it replaced it with better idioms, that still allow the
> valid uses and make bogus uses less likely.

A lot of people argued very strongly for head const.

> Here we are talking to remove a possibility, without providing something better.

December 10, 2012
On 12/9/2012 8:17 PM, Jonathan M Davis wrote:
> Not to mention, unless you can find ways to implement everything that you'd
> need a postblit or copy constructor to do without them and get rid of
> postblits, doing deep copies is going to be possible. And in the process of
> getting rid of postblits, you could easily end up disallowing other stuff which
> was useful and innocuous (e.g. something as simple as being able to print out
> when an object is copied when debugging).

Have you ever written a struct that requires a deep copy?

I have, and I always wound up redoing it so the deep copy was unnecessary.

December 10, 2012
12/10/2012 8:12 AM, Mehrdad пишет:
> On Monday, 10 December 2012 at 03:53:04 UTC, Walter Bright wrote:
>> I do not dispute that deep copy is commonly used in C++. I challenge
>> the idea that it is a good design pattern, i.e. better than using
>> copy-on-write.
>
>
>
>
> Ignoring the design issue, it's plain faster -- for COW you have to
> perform checks on every call.

On every write obviously. In short - it depends on the use case.

-- 
Dmitry Olshansky
December 10, 2012
On Monday, 10 December 2012 at 11:03:28 UTC, Walter Bright wrote:
> On 12/9/2012 8:17 PM, Jonathan M Davis wrote:
>> Not to mention, unless you can find ways to implement everything that you'd
>> need a postblit or copy constructor to do without them and get rid of
>> postblits, doing deep copies is going to be possible. And in the process of
>> getting rid of postblits, you could easily end up disallowing other stuff which
>> was useful and innocuous (e.g. something as simple as being able to print out
>> when an object is copied when debugging).
>
> Have you ever written a struct that requires a deep copy?

The talk deviated to postblit, but in the original argument, the entire point of the thread is to have extra support for reference-type objects: Objects that are basically nothing more than a pointer. You'd have a hard time doing cheaper copy than that actually.

Unfortunately, we have a problem regarding their initialization. This introduces subtle bugs, redundant "isInitialized" checks, ugly implementations etc...
December 10, 2012
On Monday, 10 December 2012 at 11:03:28 UTC, Walter Bright wrote:
>
> Have you ever written a struct that requires a deep copy?
>
> I have, and I always wound up redoing it so the deep copy was unnecessary.

How do you get around it? Let's say you have an address book structure that organizes addresses by email. Without a postblit or some deep copy, duplicating means sharing. When I see this, I think - I better add a postblit in case address books get copied. How would you approach it to not need deep copy? For something as simple as this would you introduce COW?

Thanks,
Dan

---------------------------
module phone.phone;

import std.stdio;

struct Address {
  string street;
  string zipCode;
  string state;
  string country;
}

struct AddressBook {
  alias Address[string] EmailAddressMap;

  void addAddress(string email, Address address) {
    _emailAddressMap[email] = address;
  }

  private {
    EmailAddressMap _emailAddressMap;
  }
}


unittest {
  AddressBook office;
  office.addAddress("foo@aol.com", Address("201 Foo Dr", "99999", "Fl", "USA"));
  AddressBook copy = office;
  copy.addAddress("goo@aol.com", Address("202 Foo Dr", "99999", "Fl", "USA"));
  writeln(office);
  writeln(copy);
}
December 10, 2012
On Monday, 10 December 2012 at 16:52:54 UTC, monarch_dodra wrote:
> The talk deviated to postblit, but in the original argument, the entire point of the thread is to have extra support for reference-type objects: Objects that are basically nothing more than a pointer. You'd have a hard time doing cheaper copy than that actually.
>

The postblit discussion is very relevant here.

The underlying point is the concept of ownership. When a structure contains a reference, it may own the data refered, or not.

The existence of postblit allow for struct that own their data (by default in they don't). But the struct can't assert in a first place that it own the data. It may only hope that the user did things right in the first place and act as if it does own the data. In addition, the struct have to check all over the place that owned data does exists, because it has no way to ensure they do.

The point that disallowing default constructor, and allowing postblit is inconsistent. One is made for a concept that is broken by the lack of the other. If it is really decided that ownership is a BAD THING©, then we should disable both postblit and default construction.

COW isn't a valid replacement, because it imply different tradeoff. It is good for an object that is copied a lot and not modified often (or have an expensive modification). Ownership goes the other way around : it is good for an object that isn't copied often, but get a lot of cheap modifications.
December 10, 2012
On Monday, December 10, 2012 03:02:40 Walter Bright wrote:
> On 12/9/2012 8:17 PM, Jonathan M Davis wrote:
> > Not to mention, unless you can find ways to implement everything that
> > you'd
> > need a postblit or copy constructor to do without them and get rid of
> > postblits, doing deep copies is going to be possible. And in the process
> > of
> > getting rid of postblits, you could easily end up disallowing other stuff
> > which was useful and innocuous (e.g. something as simple as being able to
> > print out when an object is copied when debugging).
> 
> Have you ever written a struct that requires a deep copy?
> 
> I have, and I always wound up redoing it so the deep copy was unnecessary.

Yes. I've done it. And I don't think that I've ever bothered with COW. The extra complication isn't generally worth it as far as I'm concerned. If I've really wanted something to be that cheap to copy around, I've usually just used a reference type and copied it explicitly when a deep copy was needed.

I have no problem with people using COW if that's what they want to do, and I may even use it at some point, but I don't want to be forced to use it in order to have structs which hold reference types to be treated as value types.

- Jonathan M Davis
December 11, 2012
On Monday, 10 December 2012 at 16:46:19 UTC, Dmitry Olshansky wrote:
> 12/10/2012 8:12 AM, Mehrdad пишет:
>> On Monday, 10 December 2012 at 03:53:04 UTC, Walter Bright wrote:
>>> I do not dispute that deep copy is commonly used in C++. I challenge
>>> the idea that it is a good design pattern, i.e. better than using
>>> copy-on-write.
>>
>>
>>
>>
>> Ignoring the design issue, it's plain faster -- for COW you have to
>> perform checks on every call.
>
> On every write obviously. In short - it depends on the use case.


lol I thought it was rather obvious that e.g. if you never do any calls to begin with then the point is moot... but thanks for the clarification lol =P