View mode: basic / threaded / horizontal-split · Log in · Help
December 04, 2012
[Issue 9112] New: Uniform default construction
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: -------
December 06, 2012
[Issue 9112] Uniform default construction
http://d.puremagic.com/issues/show_bug.cgi?id=9112


bearophile_hugs@eml.cc changed:

          What    |Removed                     |Added
----------------------------------------------------------------------------
                CC|                            |bearophile_hugs@eml.cc


--- Comment #1 from bearophile_hugs@eml.cc 2012-12-05 17:31:48 PST ---
This is useful in generic code:
int n = int(10);

So we use:
reduce!q{a + b}(T(0), items)

Instead of:
reduce!q{a + b}(cast(T)0, items)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 06, 2012
[Issue 9112] Uniform default construction
http://d.puremagic.com/issues/show_bug.cgi?id=9112


Jonathan M Davis <jmdavisProg@gmx.com> changed:

          What    |Removed                     |Added
----------------------------------------------------------------------------
                CC|                            |jmdavisProg@gmx.com


--- Comment #2 from Jonathan M Davis <jmdavisProg@gmx.com> 2012-12-05 18:12:49 PST ---
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;

auto temp = new int;
*temp = 7;
auto j = cast(immutable(int)*)temp;

Pointers to primitive types are just plain ugly to initialize, especially when
const and immutable come into play.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 06, 2012
[Issue 9112] Uniform default construction
http://d.puremagic.com/issues/show_bug.cgi?id=9112



--- Comment #3 from bearophile_hugs@eml.cc 2012-12-05 18:50:12 PST ---
(In reply to comment #2)
> What I really want to be able to do is stuff like
> 
> auto i = new int(5);

Just curious, in what cases do you need that?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 06, 2012
[Issue 9112] Uniform default construction
http://d.puremagic.com/issues/show_bug.cgi?id=9112



--- Comment #4 from Jonathan M Davis <jmdavisProg@gmx.com> 2012-12-05 19:04:49 PST ---
> Just curious, in what cases do you need that?

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: -------
December 06, 2012
[Issue 9112] Uniform default construction
http://d.puremagic.com/issues/show_bug.cgi?id=9112



--- Comment #5 from bearophile_hugs@eml.cc 2012-12-05 19:37:13 PST ---
(In reply to comment #4)

> Any time that you want create a pointer to an int - or a float or a bool or any
> of the primitive types.

This doesn't answer my question. In what cases do you want this? I think I have
never needed this:

auto i = new int(5);

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 06, 2012
[Issue 9112] Uniform default construction
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: -------
December 06, 2012
[Issue 9112] Uniform default construction
http://d.puremagic.com/issues/show_bug.cgi?id=9112



--- Comment #7 from bearophile_hugs@eml.cc 2012-12-06 04:37:51 PST ---
(In reply to comment #6)
> 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,

In D std.typecons.Nullable!int is often better than a heap-allocated int.



> Have you honestly never needed a pointer to an int?

Not that I remember.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 07, 2012
[Issue 9112] Uniform construction for built-in types
http://d.puremagic.com/issues/show_bug.cgi?id=9112


Kenji Hara <k.hara.pg@gmail.com> changed:

          What    |Removed                     |Added
----------------------------------------------------------------------------
           Summary|Uniform default             |Uniform construction for
                  |construction                |built-in types


--- Comment #8 from Kenji Hara <k.hara.pg@gmail.com> 2012-12-06 16:55:04 PST ---
I agree with Jonathan. `new immutable int(1)` is also necessary, otherwise we
cannot initialize heap-allocated value without type-system hacking (by using
cast). I think it is one of hole in current const type system.

Therefore, for all built-in types, both stack allocating syntax (T() and T(v))
and heap allocating syntax (new T() and new T(v)) should be supported. I
changed the summary. 

But, true uniform construction cannot be implemented currently, because array
construction has some special cases.
I've opened a new issue for uniform array construction.
Issue 9120 - Uniform construction for array types

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 07, 2012
[Issue 9112] Uniform construction for built-in types
http://d.puremagic.com/issues/show_bug.cgi?id=9112


monarchdodra@gmail.com changed:

          What    |Removed                     |Added
----------------------------------------------------------------------------
                CC|                            |monarchdodra@gmail.com


--- Comment #9 from monarchdodra@gmail.com 2012-12-06 22:30:28 PST ---
(In reply to comment #1)
> This is useful in generic code:
> int n = int(10);

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: -------
« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home