On Wednesday, 19 September 2012 at 18:08:15 UTC, Dmitry Olshansky wrote:
On 19-Sep-12 15:52, monarch_dodra wrote:
I realize *why* the "default" constructor had to go, but "no-arg" didn't have to go with it. I think it was an accident to let it go, and we
should be trying to fix this.

I do not feel that there is a lot of reference-like types that take 0 arguments at construction. Any meaningful examples?

There are not a lot currently. RefCounted is. PRNG should arguably be migrated to them. Containers are kind of a hybrid (but this seems to be more of a implementation detail than by concept).

About checking for "was initialized" it is indeed painful, yet I believe even C++ is in the same boat (empty shared_ptr?). Also I do suspect that in the majority of cases these are just asserts since they aim to catch logic errors in code.

No, because C++ has default constructor. Regarding D's logic error, the problem is that the lack of "no-arg" underminds the definition of "logic error": More below!

Having a way to ensure initialization statically would be nice. Currently only @disabling this() would achieve that but I suspect it's somewhat bogus ATM.

In fact having @disable this() undermines the argument for "always have T.init" strategy as generic code now have to deal with both cases.

Could I get some feedback so I could make a formal and thorough
enhancement request?

I'd rather see static opCall go and be replaced with no-arg constructor. But this alone doesn't bring much benefit (if any).

Here is a concrete example:

import std.random, std.typeconv;

void main()
{
alias RefCounted!(int, RefCountedAutoInitialize.no) RCI; //RefCountedInt
    RCI a;                      //NOT initialized
    RCI b = RefCounted!int(15); //Initialized
    RCI c = RefCounted!int();   //Initialized to int.init ... ?

    int i;

    i = a; //Logic error
    i = b; //Ok
    i = c; //Logic error?
}

The issue here is with "c". Arguably, it was not initialized. Arguably, the intent was, as opposed to "a", to initialize it to it's default value. At that point, is trying to read c a logic error? And if it is, can you really blame the user?

Same example with PRNG:

void main()
{
    alias ... PRNG;
    PRNG a;                      //NOT Seeded
    PRNG b = RefCounted!int(15); //Seeded
    PRNG c = RefCounted!int();   //Seeded with default seed...?

    a.front(); //Logic error
    b.front(); //Ok
    c.front(); //Logic error?
}

Ditto. Will the user really understand that b was seeded, yet c wasn't. This is even more ambiguous that PRNG *does* have a "seed()" method with a default seed

I know for a FACT that _I_ would have expected c to be default seeded. This makes the prng *VERY* ambiguous about whether or not it was seeded :/

Basically:
To seed with 15: PRNG b = RefCounted!int(15); //Seeded, yay
To default seed: PRNG c = RefCounted!int(); c.seed(); //  What...?

The opCall hack would fix the issue in the above example, but as stated in the previous thread, it is just that, a hack: You can't use it to construct inplace with emplace!(T, Args...), nor can you take it's address, nor can you use it to new it (should you ever want to do that.)

Reply via email to