On Tue, 05 Apr 2011 13:24:49 -0400, Regan Heath <re...@netmail.co.nz>
wrote:
On Fri, 01 Apr 2011 18:23:28 +0100, Steven Schveighoffer
<schvei...@yahoo.com> wrote:
assert("" !is null); // works on D. Try it.
Yes, but that's because this is a string literal. It's not useful where
you're getting your input from somewhere else.. like in the other 2 use
cases I mentioned.
But that isn't the same as []. Basically, if you have an existing array,
and you want to create a non-null empty array out of it, a slice of [0..0]
always works.
I know you mention it, but I want to draw attention to the original
problem, that [] returns a null array. Other cases where you are not
using [] or "" are a separate issue.
All the cases you have brought up involve strings, for which there is a
non-null array returned for "". I still have not yet seen a compelling
use case for making [] return non-null.
The other use case may be a little more problematic depending on the
method used to read the input from the keyboard, IIRC one of the methods
returns null for a blank line of input, which I would have to detect and
'fix' using emptyArray if I wanted to pass it to something that cares
about the distinction.
That is up to the implementation of that function. D provides ways to
return an empty array that does not have a null pointer.
It's one thing to want an array with a non-null pointer, but it's
another thing entirely to want an array with a non-null pointer which
points to a valid heap address.
I don't specifically want either of those things. I just want _some
way_ to represent 'exists but is empty' and for it to be different to
'does not exist'. Currently D's arrays cannot do that, yet a plain old
pointer can.
Of course they can, you can check for null vs empty using "is null" or
".empty".
The issue you may have is that phobos does not always care about
preserving this distinction. One exmaple is dup. It is pointless to dup
an empty array (even if non-null) by creating a heap allocation, so it
just returns null.
In my opinion, [] means empty array. I don't care what the pointer is,
as long as the array is empty. The implementation can put whatever
value it wants for the pointer. If it wants to put null, that is
fine. null means I want a null pointer.
If I had it my way, all array literals would be immutable, and the
pointers would point to ROM (even empty ones). We should not be
constructing array literals at runtime. But my opinion is still that
you should not count on the pointer being anything because
it's not specified what it is.
Sure, I agree with all that, but I still want some way of representing
both states and detecting both states and the problem is that if the
language cannot do it at a fundamental level, and requires some weird
hack or reliance on string literals then when I use any 3rd party
library, or phobos itself it will tell me null and I will have to guess
which state it actually means and 'fix' it manually.
The array has the ability to store whether it's null and empty or just
empty, you are just expecting every function to care about that
distinction, which most don't.
That seems to work, but it's hideous syntax for something that is not
that uncommon IMO.
My opinion is that it is uncommon, but it can be abstracted:
template emptyArray(T)
{
enum emptyArray = (cast(T*)0)[1..1];
}
rename as desired.
Not useful if you're getting your input from somewhere else, vs trying
to create a new empty array.
Again, not relevant. Getting an empty-but-not-null array from a
non-null-non-empty array is trivial. This whole thread is about [].
That said, if I were to want this I'd use the literal instead as it
seems safer, eg.
template emptyArray(T)
{
enum emptyArray = cast(T[])""[0..0];
}
Either way should be safe. Nothing should use data outside the array
bounds.
This code seems to disagree with your results for case 5 (dmd 2.052):
auto x = cast(char[])""[0..0];
assert(x.ptr != null); // no failure
Nope, my case 5 had a 'dup' which you're missing. If I add a new case
returning a literal as you have there I get the same result as you. I
was intentionally avoiding the literal because I knew it would be
non-null (I believe D null terminates literals) and because I want to be
able to detect these states on more than just empty string literals.
Quoting from your message previously (with added comment):
case 4:
return cast(char[])"".dup;
case 5:
return cast(char[])""[0..0]; // note lack of .dup
}
-Steve