June 14, 2005
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
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
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
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
"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
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
> 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
"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
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
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