www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3889] New: Forbid null as representation of empty dynamic array

reply d-bugmail puremagic.com writes:
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



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: -------
Mar 07 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889




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: -------
Nov 10 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889


Walter Bright <bugzilla digitalmars.com> changed:

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



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: -------
Nov 16 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889




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: -------
Nov 16 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889






 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: -------
Nov 17 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889




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: -------
Nov 17 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889




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: -------
Nov 17 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889




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: -------
Nov 17 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889


Jonathan M Davis <jmdavisProg gmx.com> changed:

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



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: -------
Aug 14 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889





 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: -------
Aug 14 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889




PDT ---
My point is that if it's too late to change this, then there's no point in
having the enhancement request. And I'd be very surprised if you could take
Walter into it at this point. I'm not judging whether the enhancement request
would be valuable. I'm merely saying that at this point, I think that it's too
late to make the changes for D2.

And as to enhancement requests sitting around until it becomes too late to
change things,

1. As soon as TDPL came out, it became too late to change a lot of stuff. If
there's enough value in changing it, it can still be change, but the bar is
much higher.

2. If you want changes to be made, you're going to need to discuss them in the
newsgroup and push for them to happen. You may also need to implement them (or
get someone else to implement them) and create a pull request. Enhancement
requests that just sit in bugzilla are likely to just sit in bugzilla and go
nowhere. For the most part, for them to occur, there needs to be a push for it,
and a very good set of arguments as to why the change needs to be made.

3. Given how many suggestions you're always making, I would suggest that pick
which battles you intend to fight. If you're only pushing for a couple of
enhancement requests, then you're a lot more likely to get them accepted then
if you're pushing for dozens of them. I don't know how many enhancement
requests you have sitting in bugzilla or how many you've mentioned in the
newsgroup, but you bring up new ones often enough that they risk becoming noise
that doesn't get paid attention to by any of the people who could actually make
them happen. The language is supposed to be essentially stable at this point,
and there just isn't man power to implement a deluge of enhancement requests.
So, pick whichever ones matter to you the most and push for them to get
implemented, but don't keep coming up with new enhancement requests all the
time. You obviously can if you want to, but a large portion of them are just
going to get ignored.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 14 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889


Brad Roberts <braddr puremagic.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |braddr puremagic.com



PDT ---
Careful Jonathan, you're talking as if D2 is the end of the development roadmap
for D as a language.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 14 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889




PDT ---
There's plenty more that needs to be done for D2 to be properly stable and
"complete." And even once it's fully stable, we can make changes which don't
break backwards compatibility. But I don't think that we're going to be wanting
to make much in the way of breaking changes at that point. Certainly, any such
changes will have to have very good reasons for being made.

However, we _are_ past the stage where the language is fully malleable. It's
supposed to be essentially stable with changes made as necessary to stabilize
it and make it so that all of the existing features are properly usable. We're
not looking to add or alter features left and right anymore. In that sense, D2
_is_ reaching the end of its development roadmap. At this point, most of the
work is going towards stabilizing and completing existing features, not adding
new ones.

But regardless of that, my point is that Bearophile is constantly asking for
language changes, and the fact that he's constantly asking for them means that
we couldn't possible implement them all even the language were still completely
malleable. He can't expect us to implement them all. And the fact that he asks
for so many means that each of them tends to get lost. It may be that most of
them are quite valuable and excellent ideas, but if he wants them to be paid
attention to, he's going to need to focus on the more important ones.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 14 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889




PDT ---
Ah. I should have read more carefully. I thought that you said "Careful
Jonathan, you're talking as if D2 is _at_ the end of the development roadmap
for D as a language," meaning that D2 is near the end of its development -
which in theory, it is. I misunderstood. You meant that D2 is not the end, and
I was talking like it was.

No, D2 is not the end of D's development. Presumably, we'll have a D3
eventually, so maybe such enhancement requests are worth keeping around for
that, but we probably should go through and clean many of them up. And if we
truly think that a particular enhancement request is never going to happen,
then it should be removed. This one _might_ happen in D3, so that would be an
argument for keeping it around. I'd definitely like to see the cruft removed
from bugzilla though so that there isn't as much that we have to sift through.
And I think that the fact that enhancement requests generally do need someone
championing them still holds, so just having it in bugzilla isn't going to lead
to it being implemented for D3, even if it _is_ a good idea.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 14 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com



13:40:38 PST ---
There's also:
arr = null;

Would you have to change that to `arr = []` to fit the enhancement request?
That would break so much code. 

I see no benefit to banning the usage of null. 

And to get a little personal, if you care about code readability so much, bear,
how about stopping using single-letter variable names or complex single-line
expressions in your own code?

These are some excerpts from your code:
c[r1] = [9 * i + j, (i/3*3 + j/3) * 9 + k + 81, 9 * i + k + 162, 9 * j + k +
243];
if (sr[rr = aux.r[c][r2]]++ != 0)
if (--sr[rr = aux.r[c][r2]] != 0)

Next time you talk about clarity take a look at your own code first.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 27 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3889





 There's also:
 arr = null;
 
 Would you have to change that to `arr = []` to fit the enhancement request?
 That would break so much code. 
 
 I see no benefit to banning the usage of null.
In well designed language it's good for different literals to represent different things. Ideally a 1:1 relation. This avoids troubles, and makes code reading and writing less bug prone and clear. In practice such 1:1 relation is not always possible or desirable, but it's a line guide still. In D there is already a literal that represents "empty array". Using two different literals to represent the same thing is not so do. And especially so if one of them looks much fitter to represent something else. [] is a very good literal to represent an empty array (elsewhere I have suggested to use [:] as literal to represent empty associative array, but this is not present in D), it's clear and natural for this purpose. In D "null" is a good literal to represent a pointer pointing to the default, zero address, etc. Since some time ago in D the concept of array was conflated with the concept of pointer (well, fat pointer). Some of my bug reports on this have being accepted and implemented, and lately arrays are behaving less and less as pointers. Refusing "null" as literal for an empty array is another step in such good direction. In D there is some confusion between empty array and null array. It's a problem that comes out all the time for D newbies, this is the last thread: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=33046 It's not just a problem for newbies, here there is a source of bugs for people that know some more D too. I am aware this is a small breaking change. And Walter and Andrei have the right to close down this enhancement request if they want so. But there are solid reasons behind this enhancement request.
 Next time you talk about clarity take a look at your own code first.
I don't write code like that in production code. Code is written or copied for various levels of intended usage. There are 5-minutes snippets, code for quick benchmarks or tests to show to other people, code written for online "code golf" contests, routines for small games written in a weekend, code that must be used in critical situations, library code that must be as much bug-free as possible, etc. They naturally have different level of bug-count, clarity, compactness, documentation, amount of contracts and preconditions and unit-tests, amount of brain work done on them, etc. It's wrong to think all of them must have the same characteristics and qualities. But the most important things you are missing are: - This enhancement request is about _language design_. - Bugzilla is not the place for discussions about persons. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 27 2012