View mode: basic / threaded / horizontal-split · Log in · Help
June 14, 2005
An empty array: true or false?
Using DMD 0.126, Windows 98SE.

cppstrings.html
----------
C++ strings use a function to determine if a string is empty:

    string str;
    if (str.empty())
        // string is empty

In D, an empty string is just null:

    char[] str;
    if (!str)
        // string is empty
----------

This bit of the documentation is hopelessly confusing the concepts of 
"null" and "empty".  If this D code is really supposed to be the 
equivalent of the C++ code immediately above it, then the compiler isn't 
seeing it this way.

In fact, this is testing whether str is null, not whether it is empty.

----------
import std.stdio;

void main() {
    char[] qwert = "";
    writefln(qwert.length);
    if (qwert) {
        writefln("qwert");
    }
    if (!qwert) {
        writefln("!qwert");
    }
    if (qwert == null) {
        writefln("qwert == null");
    }
    if (qwert != null) {
        writefln("qwert != null");
    }

    qwert = null;
    if (qwert) {
        writefln("qwert");
    }
    if (!qwert) {
        writefln("!qwert");
    }
    if (qwert == null) {
        writefln("qwert == null");
    }
    if (qwert != null) {
        writefln("qwert != null");
    }
}
----------
0
qwert
qwert == null
!qwert
qwert == null
----------

Whereas if it's meant to test for empty, then one should expect this output:

----------
0
!qwert
qwert == null
!qwert
qwert == null
----------

Same for arrays of other types.

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on 
the 'group where everyone may benefit.
June 14, 2005
Re: An empty array: true or false?
On Tue, 14 Jun 2005 10:29:25 +0100, Stewart Gordon <smjg_1998@yahoo.com>  
wrote:
> Using DMD 0.126, Windows 98SE.
>
> cppstrings.html
> ----------
> C++ strings use a function to determine if a string is empty:
>
>      string str;
>      if (str.empty())
>          // string is empty
>
> In D, an empty string is just null:
>
>      char[] str;
>      if (!str)
>          // string is empty
> ----------
>
> This bit of the documentation is hopelessly confusing the concepts of  
> "null" and "empty".  If this D code is really supposed to be the  
> equivalent of the C++ code immediately above it, then the compiler isn't  
> seeing it this way.
>
> In fact, this is testing whether str is null, not whether it is empty.
>
> ----------
> import std.stdio;
>
> void main() {
>      char[] qwert = "";
>      writefln(qwert.length);
>      if (qwert) {
>          writefln("qwert");
>      }
>      if (!qwert) {
>          writefln("!qwert");
>      }
>      if (qwert == null) {
>          writefln("qwert == null");
>      }
>      if (qwert != null) {
>          writefln("qwert != null");
>      }
>
>      qwert = null;
>      if (qwert) {
>          writefln("qwert");
>      }
>      if (!qwert) {
>          writefln("!qwert");
>      }
>      if (qwert == null) {
>          writefln("qwert == null");
>      }
>      if (qwert != null) {
>          writefln("qwert != null");
>      }
> }
> ----------
> 0
> qwert
> qwert == null
> !qwert
> qwert == null
> ----------
>
> Whereas if it's meant to test for empty, then one should expect this  
> output:
>
> ----------
> 0
> !qwert
> qwert == null
> !qwert
> qwert == null
> ----------
>
> Same for arrays of other types.

I reckon the only way to test for empty is:

import std.stdio;

template isEmpty(ArrayType) {
	bool isEmpty(ArrayType[] arr)
	{
		return (arr.length == 0 && arr.ptr != null);
	}
}

int main(char [][] args)
{
	char[] string;

	writefln("Setting string to null:");
	string = null;
	writefln("string is ",(isEmpty!(char)(string))?"empty":"not empty");
	
	if (string == null) writefln("and, string is the same as null");
	if (string == "") writefln("and, string is the same as \"\"");

	writefln("");
	writefln("Setting string to \"\":");
	string = "";
	writefln("string is ",(isEmpty!(char)(string))?"empty":"not empty");
	
	if (string == null) writefln("and, string is the same as null");
	if (string == "") writefln("and, string is the same as \"\"");
	
	writefln("");
	writefln("Setting length to zero:");
	string.length = 0;
	writefln("string is ",(isEmpty!(char)(string))?"empty":"not empty");
	
	if (string == null) writefln("and, string is the same as null");
	if (string == "") writefln("and, string is the same as \"\"");
	
	return 0;
}

(I appologise if you feel I am hijacking your thread but this is one of  
the things about D which annoys me, so...)

As you can see, "" is treated as being the same as null, and further "" is  
transformed into null when setting the length to 0. Both of these facts  
lead me to believe that D treats "" and null as the same thing.

Now, the problem I have with that: In concept an empty array is different  
to a non existant one, and both concepts are useful.

What is a non-existant array useful for I hear you ask, simple, it  
represents the non-existance of something, in contrast an empty array  
represents the existance of it, but also the fact that it's empty.

When is that useful, well I can think of a simple example, a web form  
contains text fields, when you recieve the form data you get  
"field1=value&field2=value&field3=value&&" where 'value' can be blank, as  
in "field1=&field2=value&&", what this tells you is that:

a. field1 was present on the form
b. no value was entered into field1

The existance or non-existance of field1 may cause different behaviour to  
the program recieving the data, i.e. if they're settings non-existance  
means "dont change the current setting" whereas "existance, but empty"  
means set it to nothing.

It has been pointed out that you can work around this deficiency with an  
AA, sure, but why should you have to?

Regan
June 14, 2005
Re: An empty array: true or false?
Adding a 3rd test, "if (string is null)". D does at least allow you to  
differentiate between a null reference and "" with 'is'. So, not all is  
lost ;)

int main(char [][] args)
{
	char[] string;

	writefln("Setting string to null:");
	string = null;
	writefln("string is ",(isEmpty!(char)(string))?"empty":"not empty");
	
	if (string is null) writefln("and, string is null");
	if (string == null) writefln("and, string == null");
	if (string == "") writefln("and, string == \"\"");

	writefln("");
	writefln("Setting string to \"\":");
	string = "";
	writefln("string is ",(isEmpty!(char)(string))?"empty":"not empty");
	
	if (string is null) writefln("and, string is null");
	if (string == null) writefln("and, string == null");
	if (string == "") writefln("and, string == \"\"");
	
	writefln("");
	writefln("Setting length to zero:");
	string.length = 0;
	writefln("string is ",(isEmpty!(char)(string))?"empty":"not empty");
	
	if (string is null) writefln("and, string is null");
	if (string == null) writefln("and, string == null");
	if (string == "") writefln("and, string == \"\"");
	
	return 0;
}

Regan

On Tue, 14 Jun 2005 23:40:52 +1200, Regan Heath <regan@netwin.co.nz> wrote:
> On Tue, 14 Jun 2005 10:29:25 +0100, Stewart Gordon <smjg_1998@yahoo.com>  
> wrote:
>> Using DMD 0.126, Windows 98SE.
>>
>> cppstrings.html
>> ----------
>> C++ strings use a function to determine if a string is empty:
>>
>>      string str;
>>      if (str.empty())
>>          // string is empty
>>
>> In D, an empty string is just null:
>>
>>      char[] str;
>>      if (!str)
>>          // string is empty
>> ----------
>>
>> This bit of the documentation is hopelessly confusing the concepts of  
>> "null" and "empty".  If this D code is really supposed to be the  
>> equivalent of the C++ code immediately above it, then the compiler  
>> isn't seeing it this way.
>>
>> In fact, this is testing whether str is null, not whether it is empty.
>>
>> ----------
>> import std.stdio;
>>
>> void main() {
>>      char[] qwert = "";
>>      writefln(qwert.length);
>>      if (qwert) {
>>          writefln("qwert");
>>      }
>>      if (!qwert) {
>>          writefln("!qwert");
>>      }
>>      if (qwert == null) {
>>          writefln("qwert == null");
>>      }
>>      if (qwert != null) {
>>          writefln("qwert != null");
>>      }
>>
>>      qwert = null;
>>      if (qwert) {
>>          writefln("qwert");
>>      }
>>      if (!qwert) {
>>          writefln("!qwert");
>>      }
>>      if (qwert == null) {
>>          writefln("qwert == null");
>>      }
>>      if (qwert != null) {
>>          writefln("qwert != null");
>>      }
>> }
>> ----------
>> 0
>> qwert
>> qwert == null
>> !qwert
>> qwert == null
>> ----------
>>
>> Whereas if it's meant to test for empty, then one should expect this  
>> output:
>>
>> ----------
>> 0
>> !qwert
>> qwert == null
>> !qwert
>> qwert == null
>> ----------
>>
>> Same for arrays of other types.
>
> I reckon the only way to test for empty is:
>
> import std.stdio;
>
> template isEmpty(ArrayType) {
> 	bool isEmpty(ArrayType[] arr)
> 	{
> 		return (arr.length == 0 && arr.ptr != null);
> 	}
> }
>
> int main(char [][] args)
> {
> 	char[] string;
>
> 	writefln("Setting string to null:");
> 	string = null;
> 	writefln("string is ",(isEmpty!(char)(string))?"empty":"not empty");
> 	
> 	if (string == null) writefln("and, string is the same as null");
> 	if (string == "") writefln("and, string is the same as \"\"");
>
> 	writefln("");
> 	writefln("Setting string to \"\":");
> 	string = "";
> 	writefln("string is ",(isEmpty!(char)(string))?"empty":"not empty");
> 	
> 	if (string == null) writefln("and, string is the same as null");
> 	if (string == "") writefln("and, string is the same as \"\"");
> 	
> 	writefln("");
> 	writefln("Setting length to zero:");
> 	string.length = 0;
> 	writefln("string is ",(isEmpty!(char)(string))?"empty":"not empty");
> 	
> 	if (string == null) writefln("and, string is the same as null");
> 	if (string == "") writefln("and, string is the same as \"\"");
> 	
> 	return 0;
> }
>
> (I appologise if you feel I am hijacking your thread but this is one of  
> the things about D which annoys me, so...)
>
> As you can see, "" is treated as being the same as null, and further ""  
> is transformed into null when setting the length to 0. Both of these  
> facts lead me to believe that D treats "" and null as the same thing.
>
> Now, the problem I have with that: In concept an empty array is  
> different to a non existant one, and both concepts are useful.
>
> What is a non-existant array useful for I hear you ask, simple, it  
> represents the non-existance of something, in contrast an empty array  
> represents the existance of it, but also the fact that it's empty.
>
> When is that useful, well I can think of a simple example, a web form  
> contains text fields, when you recieve the form data you get  
> "field1=value&field2=value&field3=value&&" where 'value' can be blank,  
> as in "field1=&field2=value&&", what this tells you is that:
>
> a. field1 was present on the form
> b. no value was entered into field1
>
> The existance or non-existance of field1 may cause different behaviour  
> to the program recieving the data, i.e. if they're settings  
> non-existance means "dont change the current setting" whereas  
> "existance, but empty" means set it to nothing.
>
> It has been pointed out that you can work around this deficiency with an  
> AA, sure, but why should you have to?
>
> Regan
June 14, 2005
Re: An empty array: true or false?
Regan Heath wrote:
<snip>
> I reckon the only way to test for empty is:
> 
> import std.stdio;
> 
> template isEmpty(ArrayType) {
>     bool isEmpty(ArrayType[] arr)
>     {
>         return (arr.length == 0 && arr.ptr != null);
>     }
> }
<snip>

Or equivalently

    return arr !is null && arr.length == 0;

or

    return arr !is null && arr == null;

or

    return arr !is null && arr == "";

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on 
the 'group where everyone may benefit.
June 14, 2005
Re: An empty array: true or false?
"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message 
news:d8m81l$n81$1@digitaldaemon.com...
> Using DMD 0.126, Windows 98SE.
>
> cppstrings.html
> ----------
> C++ strings use a function to determine if a string is empty:
>
>     string str;
>     if (str.empty())
>         // string is empty
>
> In D, an empty string is just null:
>
>     char[] str;
>     if (!str)
>         // string is empty
> ----------
>
> This bit of the documentation is hopelessly confusing the concepts of 
> "null" and "empty".  If this D code is really supposed to be the 
> equivalent of the C++ code immediately above it, then the compiler isn't 
> seeing it this way.
>
> In fact, this is testing whether str is null, not whether it is empty.

Agreed - the doc should be changed to use str.length == 0 to mean "empty" 
and/or that particular section in the cppstring.html should be removed. 
Testing the ptr isn't the same as testing for 0 length.
OTOH since other containers will likely have an "empty" or "isEmpty" member 
maybe one should be added to the builtin arrays.
June 14, 2005
Re: An empty array: true or false?
On Tue, 14 Jun 2005 23:40:52 +1200, Regan Heath wrote:


[snip]
> As you can see, "" is treated as being the same as null, and further "" is  
> transformed into null when setting the length to 0. Both of these facts  
> lead me to believe that D treats "" and null as the same thing.
> 
> Now, the problem I have with that: In concept an empty array is different  
> to a non existant one, and both concepts are useful.

Preaching to the converted here. I totally agree with you. 

An empty string and a non-existent string are two separate concepts and
both are useful.

-- 
Derek Parnell
Melbourne, Australia
14/06/2005 10:58:56 PM
June 14, 2005
Re: An empty array: true or false?
> I reckon the only way to test for empty is:
>
> import std.stdio;
>
> template isEmpty(ArrayType) {
> bool isEmpty(ArrayType[] arr)
> {
> return (arr.length == 0 && arr.ptr != null);
> }
> }

So an array with null ptr and 0 length is non-empty? That doesn't seem 
intuitive. I think the ptr is irrelevant when testing if the array has any 
elements in it or not. In fact one could argue that Walter should change the 
implicit conversion of an array from returning the ptr to returning the 
length so that the test
if (!str) {...}
is equivalent to
if (str.length != 0) {...}
instead of being equivalent to
if (str.ptr != null) {...}
as happens today.
June 14, 2005
Re: An empty array: true or false?
"Ben Hinkle" <bhinkle@mathworks.com> wrote in message 
news:d8mpoc$1571$1@digitaldaemon.com...
>> I reckon the only way to test for empty is:
>>
>> import std.stdio;
>>
>> template isEmpty(ArrayType) {
>> bool isEmpty(ArrayType[] arr)
>> {
>> return (arr.length == 0 && arr.ptr != null);
>> }
>> }
>
> So an array with null ptr and 0 length is non-empty? That doesn't seem 
> intuitive. I think the ptr is irrelevant when testing if the array has any 
> elements in it or not. In fact one could argue that Walter should change 
> the implicit conversion of an array from returning the ptr to returning 
> the length so that the test
> if (!str) {...}
> is equivalent to
> if (str.length != 0) {...}
> instead of being equivalent to
> if (str.ptr != null) {...}
> as happens today.

I should add another option is to remove the implicit conversion entirely 
and force users to say what they mean
if (!str.length) {...}
or
if (!str.ptr) {...}
June 14, 2005
Re: An empty array: true or false?
Ben Hinkle wrote:
> I should add another option is to remove the implicit conversion entirely 
> and force users to say what they mean
>  if (!str.length) {...}
> or
>  if (!str.ptr) {...}

Gets my vote. I got bitten once by 'if (!str) {...}'



-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/
June 14, 2005
Re: An empty array: true or false?
Ben Hinkle wrote:

>> I reckon the only way to test for empty is:
>> 
>> import std.stdio;
>> 
>> template isEmpty(ArrayType) {
>> bool isEmpty(ArrayType[] arr)
>> {
>> return (arr.length == 0 && arr.ptr != null);
>> }
>> } 
> 
> So an array with null ptr and 0 length is non-empty? That doesn't 
> seem intuitive.

No, because there's no array here.  There are three distinct cases to 
distinguish:
- null array reference
- empty array
- non-empty array

The code above is to test specifically for the empty array case, where a 
null array reference might have different semantics in the context.

> I think the ptr is irrelevant when testing if the array has any 
> elements in it or not. In fact one could argue that Walter should 
> change the implicit conversion of an array from returning the ptr to 
> returning the length so that the test

_The_ implicit conversion of an array? There are two:

(a) Conversion to a pointer, which obviously has to return the pointer.

(b) Conversion to a boolean, which is what this is about. A boolean 
can't hold either a pointer or a length, only true or false.

The only implicit conversion that could possibly return the length is 
conversion to a number. At the moment there is no conversion from an 
array to a number, and to introduce one would be a cause of confusion.

>  if (!str) {...}
> is equivalent to
>  if (str.length != 0) {...}
> instead of being equivalent to
>  if (str.ptr != null) {...}
> as happens today.

Huh? So that non-empty is false and empty or null is true? Sounds very 
counter-intuitive.

From the bit of the docs I quoted, I would've expected

    if (str) { ... }

to be equivalent to

    if (str.length != 0) { ... }

Stewart.

-- 
My e-mail is valid but not my primary mailbox. Please keep replies on
the 'group where everyone may benefit.
« First   ‹ Prev
1 2 3 4
Top | Discussion index | About this forum | D home