August 21, 2015
On Thursday, 20 August 2015 at 19:41:44 UTC, Jonathan M Davis wrote:
> On Thursday, 20 August 2015 at 17:50:11 UTC, Steven Schveighoffer wrote:
>> if(arr != null)
>
> Definitely don't do that. IMHO, "== null and "!= null" should be illegal. If you really want to check for null, then you need to use "is null" or "!is null", whereas if you want to check that an array is empty, check its length or call empty. By using "== null" or "!= null", you tend to give the false impression that you're checking whether the object or array is null - which is not what you're actually doing.

I disagree. `is null` is the one that should be illegal. `is` is supposed to do a bitwise comparison, but `null` is usually just a pointer/reference, while a slice consists of both a reference and a length. Which of those are compared?
August 21, 2015
On 8/21/15 7:34 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
> On Thursday, 20 August 2015 at 19:41:44 UTC, Jonathan M Davis wrote:
>> On Thursday, 20 August 2015 at 17:50:11 UTC, Steven Schveighoffer wrote:
>>> if(arr != null)
>>
>> Definitely don't do that. IMHO, "== null and "!= null" should be
>> illegal. If you really want to check for null, then you need to use
>> "is null" or "!is null", whereas if you want to check that an array is
>> empty, check its length or call empty. By using "== null" or "!=
>> null", you tend to give the false impression that you're checking
>> whether the object or array is null - which is not what you're
>> actually doing.
>
> I disagree. `is null` is the one that should be illegal. `is` is
> supposed to do a bitwise comparison, but `null` is usually just a
> pointer/reference, while a slice consists of both a reference and a
> length. Which of those are compared?

Both. null in this context is actually an array (with null pointer and zero length).

null is technically a no-type placeholder (defaulting to void * without context). In different contexts it means different things.

arr is null -> both pointer and length are 0
arr == null -> arr contains the same elements that null contains.
arr.ptr == null -> arr contains a null pointer (length could technically be non-zero).

-Steve
August 21, 2015
On 08/21/2015 01:34 PM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
> On Thursday, 20 August 2015 at 19:41:44 UTC, Jonathan M Davis wrote:
>> On Thursday, 20 August 2015 at 17:50:11 UTC, Steven Schveighoffer wrote:
>>> if(arr != null)
>>
>> Definitely don't do that. IMHO, "== null and "!= null" should be
>> illegal. If you really want to check for null, then you need to use
>> "is null" or "!is null", whereas if you want to check that an array is
>> empty, check its length or call empty. By using "== null" or "!=
>> null", you tend to give the false impression that you're checking
>> whether the object or array is null - which is not what you're
>> actually doing.
>
> I disagree. `is null` is the one that should be illegal. `is` is
> supposed to do a bitwise comparison,

If 'is null' is disallowed, what's the point of allowing '== null'?

> but `null` is usually just a
> pointer/reference,  while a slice consists of both a reference and a
> length.

There's a 'null slice'. Both pointer and length are null. It's what the implicit conversion from 'typeof(null)' yields.

> Which of those are compared?

Both. You explained it above.
August 21, 2015
On Friday, 21 August 2015 at 11:43:11 UTC, Steven Schveighoffer wrote:
> On 8/21/15 7:34 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
>> I disagree. `is null` is the one that should be illegal. `is` is
>> supposed to do a bitwise comparison, but `null` is usually just a
>> pointer/reference, while a slice consists of both a reference and a
>> length. Which of those are compared?
>
> Both. null in this context is actually an array (with null pointer and zero length).
>
> null is technically a no-type placeholder (defaulting to void * without context). In different contexts it means different things.
>
> arr is null -> both pointer and length are 0
> arr == null -> arr contains the same elements that null contains.
> arr.ptr == null -> arr contains a null pointer (length could technically be non-zero).

Thank for clarifying, I suspected that. Still not a good idea to use, IMO.
August 21, 2015
On 08/21/2015 01:43 PM, Steven Schveighoffer wrote:
> null is technically a no-type placeholder (defaulting to void * without
> context).

It now defaults to typeof(null), which is a distinct type from void*.
The same is confusingly not true for [] though, which still defaults to void[].
August 21, 2015
On Thursday, 20 August 2015 at 17:32:24 UTC, Jonathan M Davis wrote:
> On Thursday, 20 August 2015 at 17:01:07 UTC, anonymous wrote:
>> A compiler change disallowing such use of arrays was done and then reverted. See <https://issues.dlang.org/show_bug.cgi?id=4733>. I haven't followed things closely enough to give you a good summary.
>
> Basically, almost everyone wanted the change, but it broke some of Andrei and Vladamir's code,

It broke a crapton of my code.

Also, at least spell my name right please.
August 21, 2015
On Friday, 21 August 2015 at 10:50:40 UTC, Steven Schveighoffer wrote:
> On 8/20/15 11:15 PM, Jonathan M Davis wrote:
>> On Thursday, 20 August 2015 at 20:43:39 UTC, Steven Schveighoffer wrote:
>>> This makes me think you misunderstand what I am doing.
>>
>> If you care about whether an array is empty, you check whether its
>> length is 0 or you call empty (which checks whether the length is 0). If
>> you care about whether the array is null, you use "is null". I don't
>> understand what else you could possibly be doing. "!= null" is just
>> going to end up being equivalent to checking whether the length is 0,
>> because the elements won't be compared if the length is 0, but it gives
>> the false impression that you're checking whether the array is null -
>> hence why checking != null is a bad idea. What am I missing here?
>
> You're missing that null is not a pointer in this context, it's an empty array. So checking whether the array is null (i.e. empty) *is* what I'm doing, and it makes perfect sense to me. The false impression is not one of my doing. I can't help your C-based prejudices ;)

I know full-well that that's what you're doing, but that's not what your average programmer is going to expect. Anyone not intimately familiar with the ins and outs of D's arrays - or even a D programmer who's not paying really close attention - is likely to think that arr != null is checking whether the array is null - not whether the array is empty. And if I see code like that, I'm going to assume that the programmer who wrote the code really wanted was !is null but either made a mistake or didn't understand the difference between !is and != in this context.

Honestly, I think that writing code that uses != null is just as error-prone as using arrays in conditions directly. Certainly, it's just as confusing to many folks. Yes, it can work, but I think that it should be avoided, because it's often going to be misinterpreted by those reading the code, and anyone who reads the code who does understand the difference between is/!is and ==/!= is not going to know whether the person who wrote the code understood the difference and used == or != on purpose or whether they screwed up and didn't use is or !is like they should have.

I would love to see == null and != null be illegal just as much as I think that it would be great to make it illegal to use arrays in conditions. It's the same problem.

- Jonathan M Davis
August 21, 2015
On Friday, 21 August 2015 at 13:54:04 UTC, Vladimir Panteleev wrote:
> Also, at least spell my name right please.

Sorry.

- Jonathan M Davis
August 21, 2015
On Friday, 21 August 2015 at 11:43:11 UTC, Steven Schveighoffer wrote:
> On 8/21/15 7:34 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
>> On Thursday, 20 August 2015 at 19:41:44 UTC, Jonathan M Davis wrote:
>>> On Thursday, 20 August 2015 at 17:50:11 UTC, Steven Schveighoffer wrote:
>>>> if(arr != null)
>>>
>>> Definitely don't do that. IMHO, "== null and "!= null" should be
>>> illegal. If you really want to check for null, then you need to use
>>> "is null" or "!is null", whereas if you want to check that an array is
>>> empty, check its length or call empty. By using "== null" or "!=
>>> null", you tend to give the false impression that you're checking
>>> whether the object or array is null - which is not what you're
>>> actually doing.
>>
>> I disagree. `is null` is the one that should be illegal. `is` is
>> supposed to do a bitwise comparison, but `null` is usually just a
>> pointer/reference, while a slice consists of both a reference and a
>> length. Which of those are compared?
>
> Both. null in this context is actually an array (with null pointer and zero length).
>
> null is technically a no-type placeholder (defaulting to void * without context). In different contexts it means different things.
>
> arr is null -> both pointer and length are 0
> arr == null -> arr contains the same elements that null contains.
> arr.ptr == null -> arr contains a null pointer (length could technically be non-zero).

For all intents and purposes

arr is null

is equivalent to

arr.ptr is null

ptr is a read-only property, so you can only set the ptr to null if you set the array to null by assigning it null explicitly or by assigning it an array which is null. "is null" is how you're supposed to check pointers and references for null - explicitly comparing a class object to null with == is actually illegal - and I see no reason that arrays should be any different.

Regardless, using "is null" actually checks for whether an array is null, whereas "== null" checks whether it's empty and doesn't care about the ptr value - which is _not_ what most programmers are going to expect when you compare something against null.

- Jonathan M Davis
August 21, 2015
On Friday, 21 August 2015 at 09:14:16 UTC, Kagamin wrote:
> On Thursday, 20 August 2015 at 20:26:09 UTC, David Nadlinger wrote:
>> It's even worse: http://dpaste.dzfl.pl/ba3376feca8e
>>
>> The arrays are equal, but their Boolean value is not.
>>
>> I don't get how Andrei can reconcile this with his "D avoids unforced errors" stance.
>
> The only technical excuse for the bug is code breakage, which can be mostly addressed by dfix, but that's yet another problem: tools like dfix are shunned for some reason.

I don't think that the use of dfix is shunned. Rather, dfix is shunned as a solution, because it requires that you run it. Walter gets unhappy about changing compiler flags even if the fix to existing code is trivial, because it requires that someone change their build scripts. The simply fact that code broke - regardless of how easy it is to fix - seems to be enough for Walter to think that it's a terrible idea. So, given Walter's attitude on that, I don't think that it really matters how good dfix is. Even if it were guaranteed to perfectly change all code that it was run on to fix whatever broke with a compiler or library change, the fact that you had to run it to fix the breakage was already too much.

I think that most of us would agree that if a change is desirable (assuming that code breakage is not taken into account) that if dfix is able to just fix whatever code breakage occurs, then the breakage isn't a big deal (at least as long as it's made clear to everyone getting the new release what the breakage is and that dfix will fix it for them). But Walter definitely does not seem to agree with that. Breakage is breakage no matter how easy it is to fix. Upon occasion, he will agree that something is worth breaking because of some huge benefit that we get from it, but that's pretty rare, and most of stuff that folks want to see broken to clean up the language definitely doesn't bring enough of a benefit for him to agree to it.

- Jonathan M Davis