Re: char[] == null

2015-11-20 Thread Maxim Fomin via Digitalmars-d-learn
On Thursday, 19 November 2015 at 15:36:44 UTC, Steven 
Schveighoffer wrote:
On 11/19/15 3:30 AM, Jonathan M Davis via Digitalmars-d-learn 
wrote:
On Wednesday, November 18, 2015 22:15:19 anonymous via 
Digitalmars-d-learn wrote:

On 18.11.2015 22:02, rsw0x wrote:

slices aren't arrays
http://dlang.org/d-array-article.html


The language reference/specification [1] uses the term 
"dynamic array"
for T[] types. Let's not enforce a slang that's different 
from that.



[1] http://dlang.org/arrays.html


Exactly. T[] _is_ a dynamic array. Steven's otherwise 
wonderful article on
arrays in D ( http://dlang.org/d-array-article.html ) made the 
mistake of
calling the buffer that T[] points to on the GC heap (assuming 
that even
does point to the GC heap) the dynamic array. And per the 
language spec,

that's not true at all.


It was not a mistake :) It's how I still think of it. The spec 
is confusing, and my terminology, IMO, is a much more 
consistent (and accurate) way to think of it.


-Steve


Why formal definition of dynamic array caused confusion and is 
inconsistent? It is well consistent with static array and other 
aggregate types notions.


Consider this:

int *x = new int; // this is 'int type' ans it is 'dynamic'
int y;
int *a = &y;// and this is not 'int type'

The problem is treating chunk of heap memory as some kind of type 
(dynamic in this case). Type of object determines an interface of 
interacting with object while storage determines memory location 
and possibly duration of lifetime. It is possible to have object 
of any type to be allocated on different storages - for example, 
slice does not necessarily points to dynamic array (in your 
terms). C and C++ established a long tradition of such standard 
notions as object, lifetime, storage and type. From system 
language perspective calling memory a type (in other words, type 
of object depends on where it was allocated) does not make much 
sense.


Re: char[] == null

2015-11-19 Thread Kagamin via Digitalmars-d-learn
On Thursday, 19 November 2015 at 10:04:37 UTC, Spacen Jasset 
wrote:

char[] == null
vs
char[] is null

Is there any good use for char[] == null ? If not, a warning 
might be helpful.


Actually char[] == null is a more usable one.


Re: char[] == null

2015-11-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 11/19/15 5:04 AM, Spacen Jasset wrote:

On Thursday, 19 November 2015 at 08:30:54 UTC, Jonathan M Davis wrote:

On Wednesday, November 18, 2015 22:15:19 anonymous via
Digitalmars-d-learn wrote:

[...]


Exactly. T[] _is_ a dynamic array. Steven's otherwise wonderful
article on arrays in D ( http://dlang.org/d-array-article.html ) made
the mistake of calling the buffer that T[] points to on the GC heap
(assuming that even does point to the GC heap) the dynamic array. And
per the language spec, that's not true at all.

[...]


I mentioned this because it's bit of an error trap, that I fell into.

char[] == null
vs
char[] is null

Is there any good use for char[] == null ? If not, a warning might be
helpful.


Of course, if you are comparing something to an empty array, null is an 
effective literal to create one.


-Steve


Re: char[] == null

2015-11-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 11/19/15 3:30 AM, Jonathan M Davis via Digitalmars-d-learn wrote:

On Wednesday, November 18, 2015 22:15:19 anonymous via Digitalmars-d-learn 
wrote:

On 18.11.2015 22:02, rsw0x wrote:

slices aren't arrays
http://dlang.org/d-array-article.html


The language reference/specification [1] uses the term "dynamic array"
for T[] types. Let's not enforce a slang that's different from that.


[1] http://dlang.org/arrays.html


Exactly. T[] _is_ a dynamic array. Steven's otherwise wonderful article on
arrays in D ( http://dlang.org/d-array-article.html ) made the mistake of
calling the buffer that T[] points to on the GC heap (assuming that even
does point to the GC heap) the dynamic array. And per the language spec,
that's not true at all.


It was not a mistake :) It's how I still think of it. The spec is 
confusing, and my terminology, IMO, is a much more consistent (and 
accurate) way to think of it.


-Steve


Re: char[] == null

2015-11-19 Thread Chris Wright via Digitalmars-d-learn
On Thu, 19 Nov 2015 07:28:28 +0100, anonymous wrote:

> On 19.11.2015 06:18, Chris Wright wrote:
>> Just for fun, is an array ever not equal to itself?
> 
> Yes, when it contains an element that's not equal to itself, e.g. NaN.

Exactly.

If NaN-like cases didn't exist, TypeInfo_Array could have an 
optimization: if the pointers and lengths of its inputs were both equal, 
the arrays are equal. But adding this optimization would result in 
problematic behavior. Specifically:

auto a = [float.nan];
assert(a == a);  // passes under proposed optimization, fails now
assert(a == a.dup);  // fails under proposed optimization, fails now


Re: char[] == null

2015-11-19 Thread Meta via Digitalmars-d-learn

On Thursday, 19 November 2015 at 13:49:18 UTC, Meta wrote:
On Thursday, 19 November 2015 at 06:57:20 UTC, Jack Applegame 
wrote:

Really? http://dpaste.dzfl.pl/b11346e8e341


Sorry, I said the exact opposite of what I meant to say. The 
`assert(a == null)` *is* triggered because the expression `a == 
null` fails, even though a.length == 0. You should not use `a 
== null` to check if an array is empty. Always use a.length == 
0.


Actually, no it's not. Never mind.


Re: char[] == null

2015-11-19 Thread Meta via Digitalmars-d-learn
On Thursday, 19 November 2015 at 06:57:20 UTC, Jack Applegame 
wrote:

Really? http://dpaste.dzfl.pl/b11346e8e341


Sorry, I said the exact opposite of what I meant to say. The 
`assert(a == null)` *is* triggered because the expression `a == 
null` fails, even though a.length == 0. You should not use `a == 
null` to check if an array is empty. Always use a.length == 0.


Re: char[] == null

2015-11-19 Thread Jack Applegame via Digitalmars-d-learn

I prefer

import std.array;
if(!arr.empty) {}


Re: char[] == null

2015-11-19 Thread BBaz via Digitalmars-d-learn
On Wednesday, 18 November 2015 at 20:57:08 UTC, Spacen Jasset 
wrote:

Should this be allowed ?


IMHO no.

It's better to use `.length` to test if an array is empty. Why ? 
Because the day you'll have a function whose parameter is a 
pointer to an array, comparing to null will become completly 
confusing:


---
void whyPeopleShouldUseLength(char[]* buffptr)
{
if (buffptr != null && buffptr.length > 0) {}
}
---

Here you really have to test if the variable is assigned, it's 
not a shortcut to test the internal buffptr `.ptr` member.


Re: char[] == null

2015-11-19 Thread Spacen Jasset via Digitalmars-d-learn
On Thursday, 19 November 2015 at 08:30:54 UTC, Jonathan M Davis 
wrote:
On Wednesday, November 18, 2015 22:15:19 anonymous via 
Digitalmars-d-learn wrote:

[...]


Exactly. T[] _is_ a dynamic array. Steven's otherwise wonderful 
article on arrays in D ( http://dlang.org/d-array-article.html 
) made the mistake of calling the buffer that T[] points to on 
the GC heap (assuming that even does point to the GC heap) the 
dynamic array. And per the language spec, that's not true at 
all.


[...]


I mentioned this because it's bit of an error trap, that I fell 
into.


char[] == null
vs
char[] is null

Is there any good use for char[] == null ? If not, a warning 
might be helpful.


Re: char[] == null

2015-11-19 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, November 18, 2015 22:15:19 anonymous via Digitalmars-d-learn 
wrote:
> On 18.11.2015 22:02, rsw0x wrote:
> > slices aren't arrays
> > http://dlang.org/d-array-article.html
>
> The language reference/specification [1] uses the term "dynamic array"
> for T[] types. Let's not enforce a slang that's different from that.
>
>
> [1] http://dlang.org/arrays.html

Exactly. T[] _is_ a dynamic array. Steven's otherwise wonderful article on
arrays in D ( http://dlang.org/d-array-article.html ) made the mistake of
calling the buffer that T[] points to on the GC heap (assuming that even
does point to the GC heap) the dynamic array. And per the language spec,
that's not true at all.

T[] is a dynamic array, whereas T[n] is a static array. The buffer referred
to by T[] has no official name. And actually, the dynamic array really
doesn't care whether it refers to a buffer on the GC heap, on that was
malloced, a slice of a static array, etc. All of its operations are the same
regardless, and all of the work. It's just that if the dynamic array does
not refer to a buffer allocated on the GC heap for dynamic arrays, then it
doesn't have any excess capacity for the dynamic array to grow into when you
append to it, so appending to it forces the GC to reallocate its memory (as
opposed to only having to reallocate sometimes when the buffer is already
GC-allocated). And since the dynamic array itself does not manage its own
memory, if you slice something other than GC-allocated memory to get a
dynamic array, then it's up to you to make sure that you don't leak that
memory or refer to it after it's been freed. However, every other aspect of
T[] is identical regardless of what memory backs it, and most code really
doesn't care what memory backs it.

As far as the D language is concern, T[] _is_ a slice of memory, but it's
also a dynamic array, whereas the memory that it's slicing is _not_ a
dynamic array.

- Jonathan M Davis



Re: char[] == null

2015-11-19 Thread Kagamin via Digitalmars-d-learn

On Thursday, 19 November 2015 at 03:53:48 UTC, Meta wrote:
On Wednesday, 18 November 2015 at 23:53:01 UTC, Chris Wright 
wrote:

---
char[] buffer;
if (buffer.length == 0) {}
---


This is not true. Consider the following code:

import std.stdio;

void main()
{
int[] a = [0, 1, 2];
//4002E000 3
writeln(a.ptr, " ", a.length);
//Is not triggered, obviously
assert(a == null);

a.length = 0;
//4002E000 0
writeln(a.ptr, " ", a.length, " ", a);
//Is not triggered, not as obvious
assert(a == null);
}

There are cases when an array may have 0 length but a non-null 
pointer. If you want to check if an array's length is 0, you 
must explicitly check its length member. Checking if an array 
is equal to null only compares its pointer field to null. It 
does *not* check the length.


Comparison is ok, weird behavior manifests in boolean context:
void main()
{
int[] a = [0, 1, 2];
//4002E000 3
assert(a != null);
assert(!!a); //passes, ok

a.length = 0;
//4002E000 0
assert(a == null);
assert(!!a); //still passes!
}


Re: char[] == null

2015-11-18 Thread Jack Applegame via Digitalmars-d-learn

On Thursday, 19 November 2015 at 03:53:48 UTC, Meta wrote:
On Wednesday, 18 November 2015 at 23:53:01 UTC, Chris Wright 
wrote:

[...]


This is not true. Consider the following code:

import std.stdio;

void main()
{
int[] a = [0, 1, 2];
//4002E000 3
writeln(a.ptr, " ", a.length);
//Is not triggered, obviously
assert(a == null);

a.length = 0;
//4002E000 0
writeln(a.ptr, " ", a.length, " ", a);
//Is not triggered, not as obvious
assert(a == null);
}

There are cases when an array may have 0 length but a non-null 
pointer. If you want to check if an array's length is 0, you 
must explicitly check its length member. Checking if an array 
is equal to null only compares its pointer field to null. It 
does *not* check the length.


Really? http://dpaste.dzfl.pl/b11346e8e341


Re: char[] == null

2015-11-18 Thread anonymous via Digitalmars-d-learn

On 19.11.2015 06:18, Chris Wright wrote:

Just for fun, is an array ever not equal to itself?


Yes, when it contains an element that's not equal to itself, e.g. NaN.


Re: char[] == null

2015-11-18 Thread Chris Wright via Digitalmars-d-learn
On Thu, 19 Nov 2015 03:53:46 +, Meta wrote:

> On Wednesday, 18 November 2015 at 23:53:01 UTC, Chris Wright wrote:
>> ---
>> char[] buffer;
>> if (buffer.length == 0) {}
>> ---
> 
> This is not true. Consider the following code:
> 
> import std.stdio;
> 
> void main()
> {
>   int[] a = [0, 1, 2];
>  //4002E000 3
>   writeln(a.ptr, " ", a.length);
>  //Is not triggered, obviously assert(a == null);
>   
>   a.length = 0;
>  //4002E000 0
>   writeln(a.ptr, " ", a.length, " ", a);
>  //Is not triggered, not as obvious assert(a == null);
> }
> 
> There are cases when an array may have 0 length but a non-null pointer.
> If you want to check if an array's length is 0, you must explicitly
> check its length member. Checking if an array is equal to null only
> compares its pointer field to null. It does *not* check the length.

I tested the behavior and it matches what I said earlier:

---
auto c = "hello world".dup;
auto b = c[0..0];
writeln(b == null);  // prints true
writeln(b.ptr == null);  // prints false
---

This is because array comparison is a memberwise comparison and not a 
reference comparison, as you can see more clearly with:

---
enum int[] a = [1, 2, 3];
writeln(a == a.dup);// prints true
---

Or you can check the runtime's implementation of array equality at 
https://github.com/D-Programming-Language/druntime/blob/master/src/
object.d#L437 .

Just for fun, is an array ever not equal to itself?


Re: char[] == null

2015-11-18 Thread Meta via Digitalmars-d-learn
On Wednesday, 18 November 2015 at 23:53:01 UTC, Chris Wright 
wrote:

---
char[] buffer;
if (buffer.length == 0) {}
---


This is not true. Consider the following code:

import std.stdio;

void main()
{
int[] a = [0, 1, 2];
//4002E000 3
writeln(a.ptr, " ", a.length);
//Is not triggered, obviously
assert(a == null);

a.length = 0;
//4002E000 0
writeln(a.ptr, " ", a.length, " ", a);
//Is not triggered, not as obvious
assert(a == null);
}

There are cases when an array may have 0 length but a non-null 
pointer. If you want to check if an array's length is 0, you must 
explicitly check its length member. Checking if an array is equal 
to null only compares its pointer field to null. It does *not* 
check the length.


Re: char[] == null

2015-11-18 Thread Chris Wright via Digitalmars-d-learn
On Wed, 18 Nov 2015 20:57:06 +, Spacen Jasset wrote:

> Should this be allowed? What is it's purpose? It could compare two
> arrays, but surely not that each element of type char is null?
> 
> char[] buffer;
> if (buffer == null) {}

'null' is a value of ambiguous type. The compiler finds a set of 
compatible types for them by applying known implicit conversions. 'null' 
can implicitly convert to 'char[]'.

Arrays, of course, are tuples consisting of a start pointer and length. A 
null array is essentially {ptr = null, length = 0}. Array equality is 
implemented as, roughly:

---
if (a.length != b.length) return false;
foreach (i, v; a) {
  if (v != b[i]) return false;
}
return true;
---

(That's not quite how it's implemented; it uses runtime functions and 
indirection. But it's the same algorithm.)

This shows us that all 0-length arrays are equal. Pretty much as we'd 
expect. So your code is equivalent to:

---
char[] buffer;
if (buffer.length == 0) {}
---


Re: char[] == null

2015-11-18 Thread anonymous via Digitalmars-d-learn

On 18.11.2015 22:02, rsw0x wrote:

slices aren't arrays
http://dlang.org/d-array-article.html


The language reference/specification [1] uses the term "dynamic array" 
for T[] types. Let's not enforce a slang that's different from that.



[1] http://dlang.org/arrays.html


Re: char[] == null

2015-11-18 Thread rsw0x via Digitalmars-d-learn
On Wednesday, 18 November 2015 at 20:57:08 UTC, Spacen Jasset 
wrote:
Should this be allowed? What is it's purpose? It could compare 
two arrays, but surely not that each element of type char is 
null?


char[] buffer;
if (buffer == null) {}


slices aren't arrays
http://dlang.org/d-array-article.html