July 20, 2005
Hi,

This is a suggestion based on a thread from a couple of weeks ago. What about making if (array) illegal in D? I think it brings ambiguity and a high potential for errors to the language. The main two uses for this construct can already be done with a slightly more explicit syntax:

if (array.ptr == null) // Check for a kind of "non-existance."
if (array.length == 0) // Check for explicit emptiness.

On the other hand, one is not sure what if (array) by itself is supposed to mean, since it's _not_ like C. In C, if (array), where array is typically a pointer, means simply != NULL. The problem in D is that the array ptr is tricky and IMHO it's best not to interface with it directly.

I think it would be wise to remove this ambiguity. I propose two options:
1) Make if (array) equal _always_ to if (array.length).
2) Simply make it illegal.

What do you guys think? Walter?

Thanks,
--AJG.



July 20, 2005
On Wed, 20 Jul 2005 02:15:58 +0000 (UTC), AJG wrote:

> Hi,
> 
> This is a suggestion based on a thread from a couple of weeks ago. What about making if (array) illegal in D? I think it brings ambiguity and a high potential for errors to the language. The main two uses for this construct can already be done with a slightly more explicit syntax:
> 
> if (array.ptr == null) // Check for a kind of "non-existance."
> if (array.length == 0) // Check for explicit emptiness.
> 
> On the other hand, one is not sure what if (array) by itself is supposed to mean, since it's _not_ like C. In C, if (array), where array is typically a pointer, means simply != NULL. The problem in D is that the array ptr is tricky and IMHO it's best not to interface with it directly.
> 
> I think it would be wise to remove this ambiguity. I propose two options:
> 1) Make if (array) equal _always_ to if (array.length).
> 2) Simply make it illegal.
> 
> What do you guys think?

Both these suggestions wouldn't effect me.

-- 
Derek
Melbourne, Australia
20/07/2005 12:26:36 PM
July 20, 2005
On Wed, 20 Jul 2005 12:27:23 +1000, Derek Parnell <derek@psych.ward> wrote:
> On Wed, 20 Jul 2005 02:15:58 +0000 (UTC), AJG wrote:
>
>> Hi,
>>
>> This is a suggestion based on a thread from a couple of weeks ago. What about
>> making if (array) illegal in D? I think it brings ambiguity and a high potential
>> for errors to the language. The main two uses for this construct can already be
>> done with a slightly more explicit syntax:
>>
>> if (array.ptr == null) // Check for a kind of "non-existance."
>> if (array.length == 0) // Check for explicit emptiness.
>>
>> On the other hand, one is not sure what if (array) by itself is supposed to
>> mean, since it's _not_ like C. In C, if (array), where array is typically a
>> pointer, means simply != NULL. The problem in D is that the array ptr is tricky
>> and IMHO it's best not to interface with it directly.
>>
>> I think it would be wise to remove this ambiguity. I propose two options:
>> 1) Make if (array) equal _always_ to if (array.length).
>> 2) Simply make it illegal.
>>
>> What do you guys think?
>
> Both these suggestions wouldn't effect me.

:) because you're explicit all the time.

Regan

July 20, 2005
On Wed, 20 Jul 2005 02:15:58 +0000 (UTC), AJG <AJG_member@pathlink.com> wrote:
> This is a suggestion based on a thread from a couple of weeks ago. What about
> making if (array) illegal in D? I think it brings ambiguity and a high potential
> for errors to the language. The main two uses for this construct can already be
> done with a slightly more explicit syntax:
>
> if (array.ptr == null) // Check for a kind of "non-existance."
> if (array.length == 0) // Check for explicit emptiness.
>
> On the other hand, one is not sure what if (array) by itself is supposed to
> mean, since it's _not_ like C. In C, if (array), where array is typically a
> pointer, means simply != NULL. The problem in D is that the array ptr is tricky
> and IMHO it's best not to interface with it directly.
>
> I think it would be wise to remove this ambiguity. I propose two options:
> 1) Make if (array) equal _always_ to if (array.length).
> 2) Simply make it illegal.
>
> What do you guys think? Walter?

I prefer the current behaviour (for all the reasons I mentioned in the previous thread):
  http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/25804

"if (array)" is the same as "if (array.ptr)" which acts just like it does in C, comparing it to 0/null.

Essentially the "if" statement is checking the not zero state of the variable itself. In the case of value types it compares the value to 0. In the case of pointers and references it compares them to null.

In the case of an array, which (as explained in link above) is a mix/pseudo value/reference type, it compares the data pointer to null.

The reason this is the correct behaviour is that a null array has a null data pointer, but, an empty array i.e. an existing set containing no elements may have a non-null data pointer. In both cases they have a 0 length property.

Of course we could change this, we could remove the case where an array contains no items but has a non-null data pointer. This IMO would remove a useful distinction, the "existing set containing no items" would be un-representable with a single array variable. IMO that would be a bad move, the current situation(*) is good.

(*) there remains the problem where setting the length of an array sets the data pointer to null. This can change an "existing set with no elements" into a "non existant set".

Regan
July 20, 2005
>> I think it would be wise to remove this ambiguity. I propose two options:
>> 1) Make if (array) equal _always_ to if (array.length).
>> 2) Simply make it illegal.
>> 
>> What do you guys think?
>
>Both these suggestions wouldn't effect me.

I'll take that to mean "yes" if you don't mind. ;)

>-- 
>Derek
>Melbourne, Australia
>20/07/2005 12:26:36 PM


July 20, 2005
Hi Regan,

>Of course we could change this, we could remove the case where an array contains no items but has a non-null data pointer. This IMO would remove a useful distinction, the "existing set containing no items" would be un-representable with a single array variable. IMO that would be a bad move, the current situation(*) is good.

I undersntand, and I agree with your opinion. Losing this possible representation would not be good. Moreover, it is unnecessary. But my idea is not about that at all. I don't want to change the way the arrays themselves work.

As we know, all current representations will still be available via array.ptr. That's fine with me. I'll never use array.ptr, but if people need it, then it's all good. Just like regular pointers. I don't use them in D at all, but they are still useful to people.

The only thing I propose is to remove ambiguity in one kind of construct. If we take a look at the semantics of if (array), you will see what I mean when I said it's different than in C. In C, when you do

# if (array) { free(array); array = NULL; }

You are literally testing whether it is pointing to an array or not. If it is, delete it and null the pointer. It's very semantic, and very clear.

In D, on the other hand, the concept of "pointing to an array" is gone. The reference is always there. It is never null. So when you do if (array) you are saying "if this reference's pointer contains any data." That's a fine query to make, but not via if (array). To me, at least, that is not immediately clear.

Asking if (array) to me means "does this array exist?" In D, the answer is always yes. Technically the array reference is always there. Which is why as a sort of hack, array.ptr is tested instead. That's why the semantics of it are lost (or worse, mixed).

Therefore, it introduces ambiguity, which is what I want to prevent. If the meaning of an expression is not immediately clear and intuitive, I think people are going to misuse it. I can already see new programmers using that expression to test for emptiness.

That would be fine in C. In C, Empty == NotExistent. But not in D. Thus, my idea is to either make it so that it works semantically like C, or at least remove the construct to avoid those potential errors.

The worst part is that these errors would be a shifty bugs to catch. Why? Because if (array) _sometimes_ works for length, and sometimes it doesn't. That's just no good in my book.

Anyway, remember that if (array.ptr == null) will always be there.

>(*) there remains the problem where setting the length of an array sets the data pointer to null. This can change an "existing set with no elements" into a "non existant set".

This is exactly the sort of thing I meant when I said the array.ptr is tricky.
Static/Const arrays also don't help. In general, I don't think the pointer
should be messed around with unless (a) you know what you are doing and (b) it's
necessary (i.e. when the "bare metal" is needed).

Cheers,
--AJG.



July 20, 2005
On Wed, 20 Jul 2005 04:45:21 +0000 (UTC), AJG <AJG_member@pathlink.com> wrote:
>> Of course we could change this, we could remove the case where an array
>> contains no items but has a non-null data pointer. This IMO would remove a
>> useful distinction, the "existing set containing no items" would be
>> un-representable with a single array variable. IMO that would be a bad
>> move, the current situation(*) is good.
>
> I undersntand, and I agree with your opinion. Losing this possible
> representation would not be good. Moreover, it is unnecessary. But my idea is not about that at all. I don't want to change the way the arrays themselves work.

Excellent.

> As we know, all current representations will still be available via array.ptr. That's fine with me. I'll never use array.ptr, but if people need it, then it's all good. Just like regular pointers. I don't use them in D at all, but they are still useful to people.

Ok.

> The only thing I propose is to remove ambiguity in one kind of construct.

First you must convice Walter it's ambiguous, which is what you're trying to do :)
I don't think it is.

> If we take a look at the semantics of if (array), you will see what I mean when I said it's different than in C. In C, when you do
>
> # if (array) { free(array); array = NULL; }
>
> You are literally testing whether it is pointing to an array or not. If it is, delete it and null the pointer. It's very semantic, and very clear.

Sure. In your example above you represent an array with a pointer.

> In D, on the other hand, the concept of "pointing to an array" is gone.

Yes and no, slicing could be described as pointing to an array. Sure, it doesn't use a pointer per-se but when you slice you create a value type containing a pointer and length, the pointer points somewhere in the original array.

> The reference is always there. It is never null.

Yes, and I can see the angle you're taking here, but I think the current behaviour is consistent, take for example these statements:

A. The expression "if (x)" compares the variable x with null or 0.
B. Given "char[] p = null;" then "if (p)" should be FALSE.
C. Given "char[] p = "";" then "if (p)" should be TRUE.

Do you agree with those statements? If not, which ones, and why?

If you change "if (x)" for arrays to compare the length property instead of the data pointer then you invalidate all but the last statement C.

If you do that then arrays no longer behave like references, pointers, or basic types i.e. int, float, etc.

> So when you do if (array) you are saying "if this reference's pointer contains any data."

No, you're saying "is 'array' null or 0".

Given:
 - an array reference can never be null (as you say)
 - in all situations when an array reference would be null the data pointer is null

therefore, to compare the reference to null you simply compare the data pointer to null.

> That's a fine query to make, but not via if (array). To me, at least, that is not immediately clear.

It may not be immediately clear, but I believe it's consistent and unambiguous.

> Asking if (array) to me means "does this array exist?" In D, the answer is always yes.

It depends what you're referring to as the "array". Yes, a struct always exists. Yes, the reference always refers to it. But, the data pointer is the key element that either exists (not null, allocated) or does not (null). Just as in your C example above.

> Technically the array reference is always there. Which is why as a sort of hack, array.ptr is tested instead.

IMO it's not a hack, it's the correct behaviour (reasoning above) "to compare the reference to null you simply compare the data pointer to null."

> That's why the semantics of it are lost (or worse, mixed).

They're only lost where length is reassigned to 0, this is a bug IMO. Otherwise they're fine AFAICS.

> Therefore, it introduces ambiguity, which is what I want to prevent. If the meaning of an expression is not immediately clear and intuitive, I think people are going to misuse it.

Sure. I understand the point you're trying to make. I just don't agree with any of your reasoning (yet).

> I can already see new programmers using that expression to test for emptiness.

Why? It's an established fact that to check the length of an array you use the length property, it's comparable to just about any other container class in just about any language you care to name. (if not 'length' then 'size' or 'elements' or some other property/member)

> That would be fine in C. In C, Empty == NotExistent.

Not true.

char *empty = "";
char *notexistant = null;

> But not in D. Thus, my idea is to either make it so that it works semantically like C, or at least remove the construct to avoid those potential errors.
>
> The worst part is that these errors would be a shifty bugs to catch. Why?
> Because if (array) _sometimes_ works for length, and sometimes it doesn't.
> That's just no good in my book.

"if (array)" never checks length, it *always* compares 'array' (the variable) with null or 0, nothing more, nothing less. You wouldn't expect "if (x)" to call the length member of a class 'x' would you? Why would you expect it to do so for arrays?

Regan
July 20, 2005
Mr Heath, I agree with You on this.

-- 
...........
Dejan Lekic
  http://dejan.lekic.org

July 20, 2005
On Wed, 20 Jul 2005 11:21:55 +0200, Dejan Lekic wrote:

> Mr Heath, I agree with You on this.

I don't.

Does ...

  if (array) ...

test for an empty array or a non-existent array? I can't tell from the syntax. It is thus ambiguous.

  if (array.ptr == null) -- test for a non-existence.

  if (array.length == 0) -- test for emptiness

  if (array) -- test for which?


-- 
Derek Parnell
Melbourne, Australia
20/07/2005 7:47:04 PM
July 20, 2005
On Wed, 20 Jul 2005 19:49:19 +1000, Derek Parnell <derek@psych.ward> wrote:
> On Wed, 20 Jul 2005 11:21:55 +0200, Dejan Lekic wrote:
>
>> Mr Heath, I agree with You on this.
>
> I don't.
>
> Does ...
>
>   if (array) ...
>
> test for an empty array or a non-existent array?

It does what it always does, for every type in D, it tests whether 'array' is null or 0.
A null array is a non-existant array, thus it tests for a non-existant array.

> I can't tell from the
> syntax. It is thus ambiguous.

Granted, it's not 'explicit'. However, the behaviour is well defined.

The only 'catch' in this case is that an array cannot be null. However, when an array would be null it's data pointer is null, therefore testing the data pointer _is_ testing the array.

Regan
« First   ‹ Prev
1 2 3 4 5 6 7
Top | Discussion index | About this forum | D home