August 20, 2015
On Thursday, 20 August 2015 at 18:42:56 UTC, Márcio Martins wrote:
> On Thursday, 20 August 2015 at 18:04:00 UTC, Steven Schveighoffer wrote:
>> On 8/20/15 1:50 PM, Steven Schveighoffer wrote:
>>
>>> The "truthiness" of an array says it's true ONLY if both the pointer and
>>> length are 0.
>>
>> Ugh, *false* only if they are both 0. If either are not zero, then it's true.
>>
>> -Steve
>
> In other words, it's true when the pointer is not null. i.e. in the context of boolean evaluation, it has the semantics of string.ptr
>
> It's just making the concept of an empty array a grey cloud.
>
> Consider this:
>
> string a = "";
> string b;
> 	
> writeln(a ? "a" : "null");
> writeln(b ? "b" : "null");
> writeln(a.idup ? "adup" : "null");
> writeln(b.idup ? "bdup" : "null");
>
> Output:
> a
> null
> null
> null
>
>
> What?

Also, consider this:

writeln(a ? true : false);
writeln(a && a.idup);

Output:
true
false

What?

Should we consider this weird semantics and live with it, as there is nothing we can do, or is it a bug in idup()?
August 20, 2015
On 8/20/15 2:49 PM, Timon Gehr wrote:
> On 08/20/2015 08:05 PM, H. S. Teoh via Digitalmars-d wrote:
>> On Thu, Aug 20, 2015 at 01:50:11PM -0400, Steven Schveighoffer via
>> Digitalmars-d wrote:
>> [...]
>>> The main reason why it caused issues is this nice idiom:
>>>
>>> if(auto arr = someFunction())
>>> {
>>>     // use arr
>>> }
>>>
>>> This would HAVE to be split out to two statements, and the arr variable
>>> would be scoped outside of the if statement.
>> [...]
>>
>> I wish the language would accept:
>>
>>     if ((auto arr = someFunction()) !is null)
>>     {
>>         ...
>>     }
>>
>> But IIRC, auto cannot be used except at the top level expression.
>> ...
>
> You want !=, not !is.
>

Current behavior of if(auto arr = someFunction()) is to compare both pointer and length to 0, i.e. !is null.

His point is that if we could get rid of if(arr), then there would at least be a way to update existing (correct) code that doesn't involve refactoring if the given syntax was accepted.

This also would be acceptable (since not much code ever creates arrays with null pointer but non-zero length):

if((auto arr = someFunction()).ptr)

-Steve
August 20, 2015
On 8/20/15 2:43 PM, Timon Gehr wrote:
> On 08/20/2015 07:50 PM, Steven Schveighoffer wrote:
>>
>> Very true. Not much we can do about it. For now, the best thing to do is
>> always compare arrays to null instead of simply if(arr):
>>
>> if(arr != null)
>>
>> Alternatively, but a little more ugly, is to check the length:
>>
>> if(arr.length)
>
> Isn't the best way to compare to []?
>
> if(arr!=[])
>
> I think comparing to null is needlessly confusing.

Same thing. [] is null.

-Steve
August 20, 2015
On 8/20/15 3:04 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" <marcioapm@gmail.com>\"" wrote:
> On Thursday, 20 August 2015 at 18:42:56 UTC, Márcio Martins wrote:
>> On Thursday, 20 August 2015 at 18:04:00 UTC, Steven Schveighoffer wrote:
>>> On 8/20/15 1:50 PM, Steven Schveighoffer wrote:
>>>
>>>> The "truthiness" of an array says it's true ONLY if both the pointer
>>>> and
>>>> length are 0.
>>>
>>> Ugh, *false* only if they are both 0. If either are not zero, then
>>> it's true.
>>>
>>> -Steve
>>
>> In other words, it's true when the pointer is not null. i.e. in the
>> context of boolean evaluation, it has the semantics of string.ptr

Pragmatically speaking, yes. Technically, both are compared, but there are very very few cases of the array having null pointer and non-zero length.

>>
>> It's just making the concept of an empty array a grey cloud.
>>
>> Consider this:
>>
>> string a = "";
>> string b;
>>
>> writeln(a ? "a" : "null");
>> writeln(b ? "b" : "null");
>> writeln(a.idup ? "adup" : "null");
>> writeln(b.idup ? "bdup" : "null");
>>
>> Output:
>> a
>> null
>> null
>> null
>>
>>
>> What?

Yep. Just don't use the truthiness of arrays (including strings) and you will be ok. Use a.length ? "a" : "null" instead (e.g.).

I haven't used an array as a boolean in years because of this issue, I always specify whether I want pointer or length checked.

>
> Also, consider this:
>
> writeln(a ? true : false);
> writeln(a && a.idup);
>
> Output:
> true
> false
>
> What?

Yep :)

> Should we consider this weird semantics and live with it, as there is
> nothing we can do, or is it a bug in idup()?

Not a bug, idup should not consume a heap block to hold 0 elements, returning null is correct. Again, the issue is not idup, but the consideration of what the truth value of the array is.

-Steve
August 20, 2015
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.

- Jonathan M Davis
August 20, 2015
On 8/20/15 3:41 PM, 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.

On the contrary, checking if it's equal to null checks to see if it has the same elements as null. That's exactly what I would want.

If I want to check the pointer, I check arr.ptr != null.

I will note, I tend to have relatively no problem avoiding the conflation between null pointers and null arrays. That may not be true for most people, but I see them as two different things.

-Steve
August 20, 2015
On 08/20/2015 09:08 PM, Steven Schveighoffer wrote:
> On 8/20/15 2:43 PM, Timon Gehr wrote:
>> On 08/20/2015 07:50 PM, Steven Schveighoffer wrote:
>>>
>>> Very true. Not much we can do about it. For now, the best thing to do is
>>> always compare arrays to null instead of simply if(arr):
>>>
>>> if(arr != null)
>>>
>>> Alternatively, but a little more ugly, is to check the length:
>>>
>>> if(arr.length)
>>
>> Isn't the best way to compare to []?
>>
>> if(arr!=[])
>>
>> I think comparing to null is needlessly confusing.
>
> Same thing. [] is null.
>
> -Steve

Sure. I still consider arr!=[] cleaner style. YMMV.
August 20, 2015
On 08/20/2015 09:54 PM, Steven Schveighoffer wrote:
> On 8/20/15 3:41 PM, 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.
>
> On the contrary, checking if it's equal to null checks to see if it has
> the same elements as null. That's exactly what I would want.
> ...

It's about the /impression/, not about what it's actually doing. It clearly does the right thing.

> If I want to check the pointer, I check arr.ptr != null.
>
> I will note, I tend to have relatively no problem avoiding the
> conflation between null pointers and null arrays. That may not be true
> for most people, but I see them as two different things.
>
> -Steve

Sure, this is the same for me, but [] may be less confusing than null for most readers of the code and it's fewer keystrokes too.
August 20, 2015
On 08/20/2015 09:08 PM, Steven Schveighoffer wrote:
> On 8/20/15 2:49 PM, Timon Gehr wrote:
>> On 08/20/2015 08:05 PM, H. S. Teoh via Digitalmars-d wrote:
>>> On Thu, Aug 20, 2015 at 01:50:11PM -0400, Steven Schveighoffer via
>>> Digitalmars-d wrote:
>>> [...]
>>>> The main reason why it caused issues is this nice idiom:
>>>>
>>>> if(auto arr = someFunction())
>>>> {
>>>>     // use arr
>>>> }
>>>>
>>>> This would HAVE to be split out to two statements, and the arr variable
>>>> would be scoped outside of the if statement.
>>> [...]
>>>
>>> I wish the language would accept:
>>>
>>>     if ((auto arr = someFunction()) !is null)
>>>     {
>>>         ...
>>>     }
>>>
>>> But IIRC, auto cannot be used except at the top level expression.
>>> ...
>>
>> You want !=, not !is.
>>
>
> Current behavior of if(auto arr = someFunction()) is to compare both
> pointer and length to 0, i.e. !is null.
> ...

I know, and it's horrible.

> His point is that if we could get rid of if(arr), then there would at
> least be a way to update existing (correct) code that doesn't involve
> refactoring if the given syntax was accepted.
> ...

Fair enough.

> This also would be acceptable (since not much code ever creates arrays
> with null pointer but non-zero length):
>
> if((auto arr = someFunction()).ptr)
>...

It would certainly be handy, also for other usages.
August 20, 2015
On Thursday, 20 August 2015 at 16:45:18 UTC, Márcio Martins wrote:
> Having 2 empty strings evaluate differently is very unintuitive and error-prone, in my opinion.

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.

 — David