Jump to page: 1 2
Thread overview
[Issue 3889] New: Forbid null as representation of empty dynamic array
Nov 17, 2010
Walter Bright
Nov 17, 2010
Sobirari Muhomori
Nov 17, 2010
Sobirari Muhomori
Nov 17, 2010
Sobirari Muhomori
Nov 17, 2010
Sobirari Muhomori
Aug 15, 2011
Jonathan M Davis
Aug 15, 2011
Jonathan M Davis
Aug 15, 2011
Brad Roberts
Aug 15, 2011
Jonathan M Davis
Aug 15, 2011
Jonathan M Davis
Feb 27, 2012
Andrej Mitrovic
March 07, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3889

           Summary: Forbid null as representation of empty dynamic array
           Product: D
           Version: 2.040
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: bearophile_hugs@eml.cc


--- Comment #0 from bearophile_hugs@eml.cc 2010-03-07 07:08:13 PST ---
I prefer a language that uses literals that are as much as possible clear, readable and unambiguous. In D "null" can represent empty pointers, empty class references, and empty dynamic arrays:


int[] foo(int[] a) {
    return null;
}
int[] foo2(int[] a) {
    return [];
}
void main() {
    foo(cast(int[])null);
    foo(null);
    foo([]);
    foo2(cast(int[])null);
    foo2(null);
    foo2([]);
}


But "null" is not a clear way to represent an empty array, that is a struct of two items (this reminds me of the untidy usage of 0 to represent a null pointer in C). So I propose to remove the usage of "null" to represent an empty dynamic array (the Delight D-derived language already allows only [] for such purpose).


Note: [] is not fully unambiguous, it doesn't specify a type. Specifying a type can be useful, because you can use it to give as argument to a template function an array of the correct type:


import std.stdio: writeln;
void foo(T)(T[] a) {
    writeln(typeid(T));
}
void main() {
    // OK, int[]
    foo(cast(int[])null);

    // OK, int[]
    foo(cast(int[])[]);

    // Partially OK, inside foo 'a' is of type void[]
    foo([]);

    // Bad, Error: template test.foo(T) does not match any function template
declaration
    foo(null);
}


In such situations cast(int[])[] is enough. I think this idiom isn't common in
D code.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 10, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3889



--- Comment #1 from bearophile_hugs@eml.cc 2010-11-10 12:17:06 PST ---
I'd like to change this from enhancement request to bug report.

See also bug 5199

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3889


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com


--- Comment #2 from Walter Bright <bugzilla@digitalmars.com> 2010-11-16 20:15:19 PST ---
It's an enhancement request because it is working as designed.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3889



--- Comment #3 from Sobirari Muhomori <dfj1esp02@sneakemail.com> 2010-11-16 21:30:44 PST ---
>     foo(null);
>     foo([]);
>
>     // OK, int[]
>     foo(cast(int[])null);
> 
>     // OK, int[]
>     foo(cast(int[])[]);
> 
>     // Partially OK, inside foo 'a' is of type void[]
>     foo([]);

I think, null is easier to parse.
null is a handy visual anchor, but [] doesn't even look like a value, one
should spend some effort to recognize it as a value.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3889



--- Comment #4 from bearophile_hugs@eml.cc 2010-11-17 04:33:47 PST ---
(In reply to comment #3)

> I think, null is easier to parse.

Here I don't care if for 'null' is easier to parse by the compiler. Here I care more for the programmer and the semantics in his/her head. An array is not a pointer, so it's not null, it's a two-word-long struct. It's more like a <null,0> pair.


> null is a handy visual anchor, but [] doesn't even look like a value, one should spend some effort to recognize it as a value.

I don't understand what you mean. In that context [ ] are delimiters for a
particular kind of built-in collection.
So this is an array with two items inside: [1, 2]
This is an array with one items inside: [1]
And this is an (untyped) array with zero items inside: []
Understanding this sequence requires no mental efforts.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3889



--- Comment #5 from Sobirari Muhomori <dfj1esp02@sneakemail.com> 2010-11-17 12:01:15 PST ---
> Here I don't care if for 'null' is easier to parse by the compiler. Here I care more for the programmer and the semantics in his/her head.

Programmer has a parser too.

> I don't understand what you mean. In that context [ ] are delimiters for a particular kind of built-in collection.

Depending on the context, [] can have 3 meanings only one of them is value.
Meaning of null is context-independent.
If you care about semantics in one's head, here are some details: [] can have
non-null .ptr, because it's an array literal and array is usually located
somewhere in memory, ptr pointing at its beginning, so ([] is null) can be
false.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3889



--- Comment #6 from Sobirari Muhomori <dfj1esp02@sneakemail.com> 2010-11-17 12:23:21 PST ---
compare
---
foo[]=(cast(Foo[])[])[]; //copy empty array

foo[]=(cast(Foo[])null)[]; //copy null slice
---

The first line has all 3 meanings of []

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3889



--- Comment #7 from Sobirari Muhomori <dfj1esp02@sneakemail.com> 2010-11-17 12:26:41 PST ---
ps Huh, [] actually has 4 possible meanings, I forgot about either array operation or full slice operator.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 15, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=3889


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

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


--- Comment #8 from Jonathan M Davis <jmdavisProg@gmx.com> 2011-08-14 17:44:52 PDT ---
Regardless of how good or bad an idea this is, there is no way that this is going to change at this point. The current situation is very much by design and changing it would break a lot of code. So, is there any reason to keep this enhancement request open?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 15, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=3889



--- Comment #9 from bearophile_hugs@eml.cc 2011-08-14 18:29:23 PDT ---
(In reply to comment #8)
> Regardless of how good or bad an idea this is, there is no way that this is going to change at this point. The current situation is very much by design and changing it would break a lot of code.

It's a design that I don't think is the best.

1) [] and null are two ways to do the same thing (empty array literal). Well
designed languages have (try to have) only one obvious way to do something.

2) When you print an empty array writeln is supposed to write "[]", not null. Having the code use the same representation produced by writeln is very handy (example: for code generation, improve debugging output readability, etc).

3) Between [] and null the [] is more specific.

4) DMD needs to break the idea that arrays are pointers. New D programmers need to be steered as soon as possible away from the idea that D arrays are like C arrays. While the usage of null to denote empty dynamic arrays reinforces this wrong idea.

Regarding the current bad D way of mixing the idea of pointers and dynamic arrays at a visual level, see also issue 3990 that shows this example (it compiles with DMD 2.054 too):

void main() {
   int[] a1 = [5, 4, 3];
   assert(*a1 == 5);
   alias typeof(a1) T1;
   assert(is(typeof(*T1)));
   int* p1 = cast(int*)a1;
   assert(p1 == a1.ptr);
}


I don't think you will be able to ignore all the things Steven Schveighoffer says here:

http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=135391


This is not a single change, there are other related changes, see also issue 5788

A tool as Gofix gives a bit more freedom to change: http://blog.golang.org/2011/04/introducing-gofix.html


Regarding "now it's too much late to change it" see also 3843. There are several more enhancement requests in Bugzilla that as more time passes will become "now it's too much late to change".

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2