View mode: basic / threaded / horizontal-split · Log in · Help
December 01, 2012
Re: Time to kill T() as (sometimes) working T.init alias ?
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
Re: Time to kill T() as (sometimes) working T.init alias ?
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
Re: Time to kill T() as (sometimes) working T.init alias ?
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
Re: Time to kill T() as (sometimes) working T.init alias ?
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
Re: Time to kill T() as (sometimes) working T.init alias ?
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
Re: Time to kill T() as (sometimes) working T.init alias ?
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
Re: Time to kill T() as (sometimes) working T.init alias ?
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
Re: Time to kill T() as (sometimes) working T.init alias ?
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
Re: Time to kill T() as (sometimes) working T.init alias ?
> 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
Re: Time to kill T() as (sometimes) working T.init alias ?
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.
1 2 3 4 5 6 7 8
Top | Discussion index | About this forum | D home