December 01, 2012
On Saturday, 1 December 2012 at 04:32:44 UTC, Walter Bright wrote:
> On 11/30/2012 3:31 PM, Mehrdad wrote:
>> If that's the case, then we need to get rid of postblits entirely.
>
> The only justification I've ever been able to come up with for postblits is implementing a reference counting type.

Which have to check for null all over the place because it can be uninitialized.
December 01, 2012
On Saturday, December 01, 2012 15:32:39 Walter Bright wrote:
> On 11/30/2012 3:31 PM, Mehrdad wrote:
> > If that's the case, then we need to get rid of postblits entirely.
> 
> The only justification I've ever been able to come up with for postblits is implementing a reference counting type.

Any struct which contains reference types needs them. For instance, a struct containing int[] needs to dup that array if it doesn't want to have the copy referring to the same elements as the original and therefore risk having them be mutated. Arrays with immutable elements don't have that problem, but those with mutable elements (and to some extent those with const) do have such a problem, as to structs with classes or structs which are reference types, etc. I'm surprised that you'd think that postblit constructors were only useful for implementing reference counting types. IMHO, the language would be crippled without a postblit or copy constructor for structs.

- Jonathan M Davis
December 01, 2012
On Saturday, December 01, 2012 05:42:23 deadalnix wrote:
> On Saturday, 1 December 2012 at 04:32:44 UTC, Walter Bright wrote:
> > On 11/30/2012 3:31 PM, Mehrdad wrote:
> >> If that's the case, then we need to get rid of postblits entirely.
> > 
> > The only justification I've ever been able to come up with for postblits is implementing a reference counting type.
> 
> Which have to check for null all over the place because it can be uninitialized.

That's only an issue with a ref-counting type which is attempting to be non- nullable. Most shared pointers are nullable, making such checks be required regardless. In most cases, I would consider this to be a complete non-issue.

- Jonathan M Davis
December 01, 2012
On Friday, 30 November 2012 at 07:20:39 UTC, monarch_dodra wrote:
> Related:
> Why doesn't:
> "auto a = int(5);"
> work? and, even more importantly, why don't we have this? :
> "int* p = new int (5);"
> The fact that we have "T()/T(arg)", but not "int()/int(arg)" makes *zero* sense to me. THAT has been a source of initial confusion when I moved to D.

I'd like to point out that what you are describing are examples of inconsistencies in D, and inconsistencies tend to be a significant cause of productivity loss in many areas. They needlessly complicate the learning curve, the users code, and even the documentation, and unless eliminated they will forever taint the user experience to a degree.

As for the way structs are default constructed, I found it to be very difficult to comprehend. The documentation needs to be made better and more detailed. However, I've come around to think that the behaviors are correct and worth putting up with. Yes it can be very confusing at times, so if there's a way to make it less confusing, that would be a big help.

--rt

December 01, 2012
On Saturday, 1 December 2012 at 04:51:44 UTC, Jonathan M Davis wrote:
> On Saturday, December 01, 2012 05:42:23 deadalnix wrote:
>> On Saturday, 1 December 2012 at 04:32:44 UTC, Walter Bright wrote:
>> > On 11/30/2012 3:31 PM, Mehrdad wrote:
>> >> If that's the case, then we need to get rid of postblits
>> >> entirely.
>> > 
>> > The only justification I've ever been able to come up with for
>> > postblits is implementing a reference counting type.
>> 
>> Which have to check for null all over the place because it can be
>> uninitialized.
>
> That's only an issue with a ref-counting type which is attempting to be non-
> nullable. Most shared pointers are nullable, making such checks be required
> regardless. In most cases, I would consider this to be a complete non-issue.
>
> - Jonathan M Davis

The reference to the counter can be null too, not only the payload.
December 01, 2012
On Saturday, December 01, 2012 08:26:54 deadalnix wrote:
> On Saturday, 1 December 2012 at 04:51:44 UTC, Jonathan M Davis
> 
> wrote:
> > On Saturday, December 01, 2012 05:42:23 deadalnix wrote:
> >> On Saturday, 1 December 2012 at 04:32:44 UTC, Walter Bright
> >> 
> >> wrote:
> >> > On 11/30/2012 3:31 PM, Mehrdad wrote:
> >> >> If that's the case, then we need to get rid of postblits entirely.
> >> > 
> >> > The only justification I've ever been able to come up with
> >> > for
> >> > postblits is implementing a reference counting type.
> >> 
> >> Which have to check for null all over the place because it can
> >> be
> >> uninitialized.
> > 
> > That's only an issue with a ref-counting type which is
> > attempting to be non-
> > nullable. Most shared pointers are nullable, making such checks
> > be required
> > regardless. In most cases, I would consider this to be a
> > complete non-issue.
> > 
> > - Jonathan M Davis
> 
> The reference to the counter can be null too, not only the payload.

Not a big deal, because you just have it so it would only be null if the payload is null, so you wouldn't need to check it much, if ever. At most, you'd have to check it when setting the payload to something other than null, and if the counter is set to null if the payload is set to null, then you don't even need to do that.

- Jonathan M Davis
December 01, 2012
12/1/2012 8:32 AM, Walter Bright пишет:
> On 11/30/2012 3:31 PM, Mehrdad wrote:
>> If that's the case, then we need to get rid of postblits entirely.
>
> The only justification I've ever been able to come up with for postblits
> is implementing a reference counting type.

+ copy on write
+ value semantics of typically small containers*

*Small string optimization is only useful if the type has value semantics and lives on the stack.

-- 
Dmitry Olshansky
December 01, 2012
12/1/2012 1:38 AM, Jonathan M Davis пишет:
> On Friday, November 30, 2012 23:34:04 Dmitry Olshansky wrote:
>> 11/30/2012 3:31 AM, Jonathan M Davis пишет:
>>> I'm all for T() meaning T.init if T doesn't have a static opCall, but T()
>>> shouldn't be guaranteed to be T.init. I'd very much like to see code like
>>>
>>> auto t = T();
>>>
>>> to continue to work regardless of whether T has a static opCall or not.
>>
>> And what you'd expect 't' to be then? And why such code is useful
>> anyway? The only sane way I see is to make it an explicit call of 0-arg
>> constructor then one can safely assume:
>> 1. t is of type T
>> 2. t is properly constructed and not some invalid state like T.init may be
>>
>> Currently with opCall it could be anything otherwise it ends up T.init
>> or compiler error if T is a built-in type.
>
> If
>
> auto t = T();
>
> works then you don't have to care whether the type has a static opCall or not.
> You get the most valid default-constructed object that there is (or at least,
> the closest thing that there is to a default-constructed object). If that's
> init, then it's init. If it's static opCall, then it's static opCall. I don't
> want to have to care which it is. Also, if I see
>
> T t;
>
> I'm likely to think that was supposed to be initialized, but the programmer
> forgot, whereas with
>
Then I'd say
T t = T.init;
for when you want explicitness.

Other then this I've come to rely on
T t;
being default constructed and not rising an eyebrow.

It's only in context such as these 3 lines :
T x = blah;
U y = bleh;
W w;

That I'd think w == T.init might be unintended.

> auto t = T();
>
> it's clear that that it was intended to be initialized to whatever T() is (be
> it T.init or the result of a static opCall), and it's clear that the
> programmer didn't forget to initialize it.

Either way my final proposal doesn't remove it. In short it goes as follows:

- allow 0-arg constructors for consistency and cross-cutting issues (like all default args ctor)
- use a default one (as is done with per-field constructors) if none or user defined match. The default will blit object with T.init.

It'd let static opCall be there as is. It will just put them in the same overload set as constructors.

-- 
Dmitry Olshansky
December 01, 2012
> Either way my final proposal doesn't remove it. In short it goes as
> follows:
>
> - allow 0-arg constructors for consistency and cross-cutting issues
> (like all default args ctor)
> - use a default one (as is done with per-field constructors) if none or
> user defined match. The default will blit object with T.init.
A typo:
... if none OF user-defined match.


-- 
Dmitry Olshansky
December 03, 2012
On 12/1/2012 6:26 PM, deadalnix wrote:
> The reference to the counter can be null too, not only the payload.

Or you can embed the counter in the type, and there is no reference to it.