July 12, 2022
On 12.07.22 22:14, H. S. Teoh wrote:
> Pedantically, no, they're not the same. You can assign null to a
> pointer, but you can't assign [] to a pointer. `null` is a supertype of
> `[]`.
> 
> But probably nobody actually cares about this distinction. :-D

If we're ignoring context, "null" has four characters, while "[]" has only two. Clearly, they're not similar at all.

The context was arrays, not pointers. `void f(T[] a = null) {}` has exactly the same meaning as `void f(T[] a = []) {}`.
July 12, 2022

On Tuesday, 12 July 2022 at 19:55:46 UTC, ag0aep6g wrote:

>

On Tuesday, 12 July 2022 at 19:02:01 UTC, user1234 wrote:

>

On Tuesday, 12 July 2022 at 16:40:38 UTC, H. S. Teoh wrote:
[...]

>

Do not rely on this, however;

Absolutely. I'd like to add: especially as default parameter value that's an array. Never use null. use [] (empty array literal).

Just to be clear: [] and null are the exact same thing (null pointer, zero length). The reason to prefer [] over null is purely for readability. The meaning is exactly the same.

ah yes. The case I thought to was actually

void test1(string s = null)
{
    assert(s is null);
}

void test2(string s = "") // s is null term'ed, i.e not null
{
    assert(s is null);
}

void main()
{
    test1();
    test2(); // fails
}

the rule of thumb is to use stuff.length as condition, always, and not stuff itself, to prevent natyx, hard to find bugs.

July 12, 2022

On Tuesday, 12 July 2022 at 18:56:43 UTC, Paul Backus wrote:

>

On Tuesday, 12 July 2022 at 16:40:38 UTC, H. S. Teoh wrote:

>

Because an empty string is, by default, represented by an empty slice of the null pointer.

Do not rely on this, however; it's possible sometimes to get an empty string that isn't null, e.g., if you incrementally shrink a slice over a string until it's empty. In that case, .ptr will not be null, but the string will still be empty. Always compare strings against "" rather than null, because the latter may not do what you think it does sometimes.

This is actually 100% reliable when comparing with the == operator because two empty strings always compare equal with ==, regardless of what they point to.

string s = "hello";
string empty1 = s[0 .. 0];
string empty2 = s[1 .. 1];
assert(empty1 == null);
assert(empty2 == null);
assert(empty1 == empty2);

The real problem is that s == null looks like it does one thing (test for a null pointer) while actually doing something slightly different (test for an empty string).

Then:

string a = null;
assert(a is null);
assert(a == "");

string b = "");
assert(b !is null);
assert(b == "");

Honestly, it is difficult to understand for newcomers... there is a reason, but there is a reason in javascript for 0 == '' too

July 12, 2022

On Tuesday, 12 July 2022 at 20:36:03 UTC, Antonio wrote:

>

Honestly, it is difficult to understand for newcomers... there is a reason, but there is a reason in javascript for 0 == '' too

Correction

string a = null;
assert(a is null);
assert(a == "");

string b = "";
assert(b !is null);
assert(b == null);
July 12, 2022

On 7/12/22 4:36 PM, Antonio wrote:

>

On Tuesday, 12 July 2022 at 18:56:43 UTC, Paul Backus wrote:

>

On Tuesday, 12 July 2022 at 16:40:38 UTC, H. S. Teoh wrote:

>

Because an empty string is, by default, represented by an empty slice of the null pointer.

Do not rely on this, however; it's possible sometimes to get an empty string that isn't null, e.g., if you incrementally shrink a slice over a string until it's empty. In that case, .ptr will not be null, but the string will still be empty. Always compare strings against "" rather than null, because the latter may not do what you think it does sometimes.

This is actually 100% reliable when comparing with the == operator because two empty strings always compare equal with ==, regardless of what they point to.

    string s = "hello";
    string empty1 = s[0 .. 0];
    string empty2 = s[1 .. 1];
    assert(empty1 == null);
    assert(empty2 == null);
    assert(empty1 == empty2);

The real problem is that s == null looks like it does one thing (test for a null pointer) while actually doing something slightly different (test for an empty string).

Then:

string a = null;
assert(a is null);
assert(a == "");

string b = "");
assert(b !is null);
assert(b == null);

Honestly, it is difficult to understand for newcomers... there is a reason, but there is a reason in javascript for 0 == '' too

It's not just for null. And it's unrelated to what javascript is doing.

string a = "abcabc";
assert(a[0 .. 3] ==  a[3 .. $])
assert(a[0 .. 3] !is a[3 .. $])

The point is, == compares value, is always compares identity.

And you cannot override is, it must always be predictable. For arrays, of course, you can't override ==, but custom types can.

-Steve

July 15, 2022

Hi @Steven Schveighoffer,
Yes solution looking useful and sure it will work.

Thanks.

July 15, 2022

On Tuesday, 12 July 2022 at 22:58:32 UTC, Steven Schveighoffer wrote:

>
string a = "abcabc";
assert(a[0 .. 3] ==  a[3 .. $])
assert(a[0 .. 3] !is a[3 .. $])

The point is, == compares value, is always compares identity.

Consider null type array which is a related topic but it cannot get a null element! The first is ok, but the second is legal. So no effect, is it normal?

auto p = [ null, null ];//*
  assert(
    is(typeof(null)[] :
       typeof(p)
    )
  ); /* and it has two(2) elements */

  p ~= null;             // okay
  assert(p.length == 3); // true

  p ~= [];               // legal (no error)
  assert(p.length != 4); // what! (no effect)

  assert(p[0] == []);    // true
  assert([] == null);    // right on

  import std.stdio;
  typeid(p).write(": ", p.length);
  writeln("->", []); // typeof(null)[]: 3->[]

SDB@79

July 15, 2022

On Friday, 15 July 2022 at 06:38:58 UTC, Salih Dincer wrote:

>

Consider null type array which is a related topic but it cannot get a null element! The first is ok, but the second is legal. So no effect, is it normal?

auto p = [ null, null ];//*
  assert(
    is(typeof(null)[] :
       typeof(p)
    )
  ); /* and it has two(2) elements */

  p ~= null;             // okay
  assert(p.length == 3); // true

  p ~= [];               // legal (no error)
  assert(p.length != 4); // what! (no effect)

  assert(p[0] == []);    // true
  assert([] == null);    // right on

  import std.stdio;
  typeid(p).write(": ", p.length);
  writeln("->", []); // typeof(null)[]: 3->[]

Yes, this is expected.

Note that the term null and [] are special tokens that morph type to whatever is most appropriate at the time. null implicitly can be typed as any pointer type, or any array type. [] can be typed as any array type. However, it can't be implicitly typed as typeof(null), which is a special unit type.

typeof(null) x;
x = []; // error;

So consider that appending an element type to an array increases the array size, whereas appending an array type to an array adds the elements of the latter to the former. In this case, zero elements.

There are still some inconsistencies though:

pragma(msg, typeof([])); // void[], likely to avoid breaking code.
void[][] arr;
arr ~= []; // does not append an element

int[] x = [1, 2];
int[] y = null; // ok, null implicitly converts to any array
x ~= y; // ok, no elements added
x ~= null; // error, does not consider the implicit conversion to int[]

-Steve

July 15, 2022

On Friday, 15 July 2022 at 11:12:07 UTC, Steven Schveighoffer wrote:

>

Note that the term null and [] are special tokens that morph type to whatever is most appropriate at the time. null implicitly can be typed as any pointer type, or any array type. [] can be typed as any array type. However, it can't be implicitly typed as typeof(null), which is a special unit type.

Thank you. I didn't know what to do with a null array though? I think void[] would be more useful.

SDB@79

July 18, 2022

On Tuesday, 12 July 2022 at 20:36:03 UTC, Antonio wrote:

>

Honestly, it is difficult to understand for newcomers... there is a reason, but there is a reason in javascript for 0 == '' too

People would have different preferences there. Difference between null and empty is useless. D does the right thing here, what other languages do, is a mistake. If you want such difference, use the Nullable wrapper or Algebraic.