Jump to page: 1 2 3
Thread overview
[Issue 9112] New: Uniform default construction
Dec 04, 2012
Kenji Hara
Dec 06, 2012
Jonathan M Davis
Dec 06, 2012
Jonathan M Davis
Dec 06, 2012
Jonathan M Davis
[Issue 9112] Uniform construction for built-in types
Dec 07, 2012
Kenji Hara
Dec 07, 2012
Kenji Hara
Dec 07, 2012
Andrej Mitrovic
Dec 07, 2012
Andrej Mitrovic
Dec 07, 2012
Jonathan M Davis
Dec 07, 2012
Jonathan M Davis
Dec 11, 2012
Kenji Hara
Dec 11, 2012
Kenji Hara
Jan 13, 2013
yebblies
Jan 13, 2013
Andrej Mitrovic
Feb 05, 2013
Andrej Mitrovic
December 04, 2012
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
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
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
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
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
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
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
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
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
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