http://d.puremagic.com/issues/show_bug.cgi?id=9112
Summary: Uniform default construction
Product: D
Version: D2
Platform: All
OS/Version: All
Status: NEW
Severity: enhancement
Priority: P2
Component: DMD
AssignedTo: nobody puremagic.com
ReportedBy: k.hara.pg gmail.com
--- Comment #0 from Kenji Hara <k.hara.pg gmail.com> 2012-12-03 20:06:08 PST ---
Related: http://d.puremagic.com/issues/show_bug.cgi?id=8752
Built-in .init property is useful, but it is sometimes unsafe, and many people
might confuse the default initializer and construction.
- Default initializer represents pre-constructing object state.
Users can access to it by using built-in `.init` property.
- Default construction is a default operation which constructing an object
completely.
* For built-in types (int, double, pointers, arrays) and class types,
default construction does nothing. Because, after initializing by
default initializer, the object is already completely constructed.
* For struct types, it is same in basic. After initialized by S.init,
the object is completely constructed. Except:
+ If S is a nested struct, default construction should fill
its frame pointer. So default construction is valid only in
the function where S is defined.
+ If S is a struct which has ` disable this();`, default construction
is disabled explicitly. So default construction is never occur.
Instead, users should call explicitly defined user-defined
constructor which has arguments.
Well, for struct types, default construction has an explicit syntax S().
But, built-in types does not have that. It is inconsistent.
So I'd like to propose new syntax to reduce such concept confusion.
int n = int(); // same as int.init
int n = int(10); // same as cast(int)10;
From the meta-programming view, we can represent default construction of value
types by T().
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------

Any time that you want create a pointer to an int - or a float or a bool or any
of the primitive types. Right now, you're forced to do two-part initialization
instead of initializing it to a value other than init when constructing it,
which is particularly bad when const or immutable is involved.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------

http://d.puremagic.com/issues/show_bug.cgi?id=9112
--- Comment #6 from Jonathan M Davis <jmdavisProg gmx.com> 2012-12-05 21:42:28
PST ---
Personally, I've used it so that an integer could be null in cases where I
needed to distinguish between having a specific value and having no value at
all, but there are plenty of other uses for it. Have you honestly never needed
a pointer to an int? It's needed less than some other things to be sure, but
there are times when it is needed, and constructing such pointers is horrible
with how things stand. It also makes constructing them generically very
difficult, which is precisely what Kenji is bringing up in this enhancement
request. It's just that he's talking about them when they're on the stack, and
I'm pointing out that it would also be valuable to do the same with the heap.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------

EXTREMELY useful. Just the other day, I was writing a unittest to cover
appender with as many types as possible, and wanted to write something along
the lines of:
//----
foreach (SS; TypeTuple!(int, S0, S1, S2, S3, S4, S5, S6, S7))
{
foreach (S; TypeTuple!(SS, const(SS), immutable(SS)))
{
auto app1 = appender!(S[])();
foreach(i; 0 .. 0x20000)
app1.put(S(i)); // HERE
//----
Long story short: "int" didn't make it into the final test...
(In reply to comment #2)

What I really want to be able to do is stuff like
auto i = new int(5);
auto j = new immutable(int)(7);
Right now, you have to do nonsense like
auto i = new int;
*i = 5;

You always have the
auto j = [cast(immutable int)5].ptr;
"Trick". But that's still ugly as sin, and I'm not sure what you are actually
paying for when doing this.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------

So I'd like to propose new syntax to reduce such concept confusion.
int n = int(10); // same as cast(int)10;

So we're introducing C++-style casts into D? This means you can no longer
search for 'cast' and expect to find all the unsafe casts in your code. I'm
very much against this, and if I remember right Walter was also against this.

From the meta-programming view, we can represent default construction of value
types by T().

We can also use a library template to do it without introducing new syntax. If
orthogonality is needed because of metaprogramming then why not just implement
a template in Phobos?
We really don't need 10 ways of doing the same thing with a different syntax..
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------

So I'd like to propose new syntax to reduce such concept confusion.
int n = int(10); // same as cast(int)10;

So we're introducing C++-style casts into D? This means you can no longer
search for 'cast' and expect to find all the unsafe casts in your code. I'm
very much against this, and if I remember right Walter was also against this.

So we're introducing C++-style casts into D? This means you can no longer
search for 'cast' and expect to find all the unsafe casts in your code. I'm
very much against this, and if I remember right Walter was also against this.

I'd actually argue for making it so that no explict casting is involved. It
could be restricted to cases where
T var = literal;
and
T var = T(literal);
would be identical. So, stuff like ubyte(12345) would be illegal whereas
cast(ubyte)12345 would be legal. It then looks like a C++ cast but isn't. It
solves the problem with generic code without causing any issues you get with
casts.

We can also use a library template to do it without introducing new syntax. If
orthogonality is needed because of metaprogramming then why not just implement
a template in Phobos?

I tried that. Andrei rejected it, and it's not worth my time to fight him over
it. Not to mention, I've always thought that
auto i = new int(7);
auto j = new immutable(int)(5);
should be legal and think that having to do something like makeNew!int(7) is a
bit of a hack anyway, since it's specifically working around a deficiency in
the language.

We really don't need 10 ways of doing the same thing with a different syntax..

AFAIK, it's not exactly the same thing, as int(10) would be only a
constructor, so would not downcast.

I agree, but if you look at Kenji's proposal, he specifically says that there's
a cast involved (which I'd missed when I read it the first time). So, Andrej's
complaint is completely valid given Kenji's initial proposal. But if you fix it
so that no cast is involved, then I think that it's fine.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------

AFAIK, it's not exactly the same thing, as int(10) would be only a
constructor, so would not downcast.

I agree, but if you look at Kenji's proposal, he specifically says that there's
a cast involved (which I'd missed when I read it the first time). So, Andrej's
complaint is completely valid given Kenji's initial proposal. But if you fix it
so that no cast is involved, then I think that it's fine.

I'm just wondering if that's *actually* what's going on, or if Kenji just
accidentally miss-commented it that way.
I don't know how to read compiler code, so I wouldn't know what he actually
did. It'd be nice if he did deliver a fail_compile checking this.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------

AFAIK, it's not exactly the same thing, as int(10) would be only a
constructor, so would not downcast.

I agree, but if you look at Kenji's proposal, he specifically says that there's
a cast involved (which I'd missed when I read it the first time). So, Andrej's
complaint is completely valid given Kenji's initial proposal. But if you fix it
so that no cast is involved, then I think that it's fine.

I'm just wondering if that's *actually* what's going on, or if Kenji just
accidentally miss-commented it that way.
I don't know how to read compiler code, so I wouldn't know what he actually
did. It'd be nice if he did deliver a fail_compile checking this.

You pointed out is correct.
At first, I had considered that int(10) should be translated to cast(int)10.
But, while implementing pull, I had discovered the incorrect cast would occur
much easily.
So now, the posted pull doesn't implement int(10) as a cast, and the syntax
accepts only a value which implicitly convertible to int.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------

Sorry, I had temporarily closed it so auto tester result had been broken in
64bit platforms.
After fixing test cases, I reopened that.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------