www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - What is 'is' supposed to tell us?

reply Derek Parnell <derek psych.ward> writes:
I think I was under a misapprehension. I thought that we could use the 'is'
operator to tell us if two objects were in fact the same instantiation or
thing. However, this result below surprised me...

  class Foo{}
  Foo a;
  Foo b;

  writefln("a is b: %s", cast(bool)(a is b != 0));
==> Result ...

  a is b: true

But it's pretty clear to me that a is not b. Even though they are both not
instantiated yet, they are still not the same something. Is this supposed
to happen? <rhetorical> If so, should it be explicitly
documented?</rhetorical>

-- 
Derek Parnell
Melbourne, Australia
http://www.dsource.org/projects/build/ v2.05 released 02/May/2005
http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage
3/05/2005 10:00:28 AM
May 02 2005
next sibling parent reply Brad Beveridge <brad somewhere.net> writes:
Derek Parnell wrote:
 I think I was under a misapprehension. I thought that we could use the 'is'
 operator to tell us if two objects were in fact the same instantiation or
 thing. However, this result below surprised me...
 
   class Foo{}
   Foo a;
   Foo b;
 
   writefln("a is b: %s", cast(bool)(a is b != 0));
 ==> Result ...
 
   a is b: true
 
 But it's pretty clear to me that a is not b. Even though they are both not
 instantiated yet, they are still not the same something. Is this supposed
 to happen? <rhetorical> If so, should it be explicitly
 documented?</rhetorical>
 

return true? Also, what is the precidence of the != operator vs "is"? Brad
May 02 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Tue, 03 May 2005 12:13:52 +1200, Brad Beveridge wrote:

 Derek Parnell wrote:
 I think I was under a misapprehension. I thought that we could use the 'is'
 operator to tell us if two objects were in fact the same instantiation or
 thing. However, this result below surprised me...
 
   class Foo{}
   Foo a;
   Foo b;
 
   writefln("a is b: %s", cast(bool)(a is b != 0));
 ==> Result ...
 
   a is b: true
 
 But it's pretty clear to me that a is not b. Even though they are both not
 instantiated yet, they are still not the same something. Is this supposed
 to happen? <rhetorical> If so, should it be explicitly
 documented?</rhetorical>
 

return true?

Yes, they are both null, but that is their *value* not their identity, no?
 Also, what is the precidence of the != operator vs "is"?

The "is" is evaluated before the "!=", otherwise the phrase ... (a is b != 0) would have been interpreted as a is (b != 0) and that won't compile. -- Derek Melbourne, Australia 3/05/2005 10:14:14 AM
May 02 2005
next sibling parent Derek Parnell <derek psych.ward> writes:
On Tue, 3 May 2005 10:17:15 +1000, Derek Parnell wrote:


[snip]
 Also, what is the precidence of the != operator vs "is"?

The "is" is evaluated before the "!=", otherwise the phrase ... (a is b != 0) would have been interpreted as a is (b != 0) and that won't compile.

I take that back. They are equal precedence. (0 != a is b) fails to compile too. -- Derek Parnell Melbourne, Australia http://www.dsource.org/projects/build/ v2.05 released 02/May/2005 http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage 3/05/2005 10:19:18 AM
May 02 2005
prev sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
The pointer's value, most logically.  How else is it supposed to 
differentiate them?  I mean, what about this:

Foo a = null;
Foo b = null;

a = b;

Should a === b now?  How is it supposed to know?  I mean, I thought it 
was the same as:

Foo* a = null;
Foo* b = null;

a = b;

Where a === b would be... well, a == b.  A comparison of the pointers - 
which tells you if they are pointing to the same data.  Which tells if 
they are the same.

-[Unknown]


 Yes, they are both null, but that is their *value* not their identity, no?

May 02 2005
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 02 May 2005 18:37:06 -0700, Unknown W. Brackets wrote:

 Yes, they are both null, but that is their *value* not their identity, no?


 The pointer's value, most logically.  How else is it supposed to 
 differentiate them?

I thought that an object's 'identity' is their address on the heap. If something doesn't have a heap address then what is it's identity? Is it the stack address? Or is it 'unknown'? In which case how we make sense of "<unknown> is <something>". I think that what D should be doing is that if either object in an 'is' operation is null, then the operation should return 'false'.
  I mean, what about this:
 
 Foo a = null;
 Foo b = null;
 
 a = b;
 
 Should a === b now?  How is it supposed to know?  I mean, I thought it 
 was the same as:
 
 Foo* a = null;
 Foo* b = null;
 
 a = b;
 
 Where a === b would be... well, a == b.  A comparison of the pointers - 
 which tells you if they are pointing to the same data.  Which tells if 
 they are the same.

But if an object is null, it is not pointing to anything. So, are two things that are not pointing to anything the same thing? -- Derek Melbourne, Australia 3/05/2005 11:58:39 AM
May 02 2005
next sibling parent Derek Parnell <derek psych.ward> writes:
On Tue, 3 May 2005 12:05:29 +1000, Derek Parnell wrote:

 I think that what D should be doing is that if
 either object in an 'is' operation is null, then the operation should
 return 'false'.

Nope, that doesn't work either. How about if both operands in an 'is' operation are objects and both are null then the operation should return false. Thus ... Foo a; Foo b; a is null ==> true b is null ==> true a is b ==> false Then again, maybe it doesn't matter in practice. If something is null, we probably aren't going to use it anyway. -- Derek Melbourne, Australia 3/05/2005 12:08:29 PM
May 02 2005
prev sibling next sibling parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
Personally, I think this is overcomplicating it.  As is, the current 
code simplifies rather directly without any special cruft: ===/is simply 
means the pointers are equal (whether the pointer is zero or otherwise.)

Adding complications where it means that only if both arguments are not 
null, or if one is the keyword null.  That's confusing, and will (for 
most comparisons, which will not involve the keyword) be slower - no?

-[Unknown]


 But if an object is null, it is not pointing to anything. So, are two
 things that are not pointing to anything the same thing?

May 02 2005
prev sibling parent reply David Medlock <amedlock nospam.org> writes:
Derek Parnell wrote:

 On Mon, 02 May 2005 18:37:06 -0700, Unknown W. Brackets wrote:
 
 
Yes, they are both null, but that is their *value* not their identity, no?


The pointer's value, most logically.  How else is it supposed to 
differentiate them?

I thought that an object's 'identity' is their address on the heap.

their identity are equal. I don't see the confusion. Its sorta like me asking you to compare two letters I never mailed to you. -David
May 03 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Tue, 03 May 2005 08:13:20 -0400, David Medlock wrote:

 Derek Parnell wrote:
 
 On Mon, 02 May 2005 18:37:06 -0700, Unknown W. Brackets wrote:
 
 
Yes, they are both null, but that is their *value* not their identity, no?


The pointer's value, most logically.  How else is it supposed to 
differentiate them?

I thought that an object's 'identity' is their address on the heap.

their identity are equal.

If an object's identity is its heap address, and the object doesn't have a heap address, does that mean it also has no identity? And if two objects both have no identity, how can one compare their non-existent identities?
 I don't see the confusion.

Consider this code snippet ... Foo a; Foo b; If 'a' and 'b' have the same identity then why are there two declarations? This is of course rhetorical, because there are two declarations because they are not the same thing. They are two distinct object reference place holders, even though they have the same 'identify value', namely null. But really, I'm over this storm-in-a-teacup. It isn't really worth the effort to keep at it. -- Derek Parnell Melbourne, Australia http://www.dsource.org/projects/build v2.05 is now available. 02/May/2005 3/May/2005 10:42:26 PM
May 03 2005
parent reply "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message
news:13g161uno61f5$.1myvvz0xtevpc.dlg 40tude.net...
 On Tue, 03 May 2005 08:13:20 -0400, David Medlock wrote:


 Consider this code snippet ...

    Foo a;
    Foo b;

 If 'a' and 'b' have the same identity then why are there two declarations?
 This is of course rhetorical, because there are two declarations because
 they are not the same thing. They are two distinct object reference place
 holders, even though they have the same 'identify value', namely null.

 -- 
 Derek Parnell
 Melbourne, Australia
 http://www.dsource.org/projects/build v2.05 is now available. 02/May/2005
 3/May/2005 10:42:26 PM

There are two declarations, because there are two names. Those two names can have different identities, or they can have the same identity. If they are both null, then they both have the same identity. I know this is not intuitive to everyone, and it is also not the only possible way to impliment the concept of "null" but it is both simple and common. TZ
May 04 2005
parent reply Sean Kelly <sean f4.ca> writes:
In article <d59tqk$1d9o$1 digitaldaemon.com>, TechnoZeus says...
There are two declarations, because there are two names.
Those two names can have different identities, or they can have the same
identity.
If they are both null, then they both have the same identity.

I think the confusion stems from the fact that null is a trap value, similar in some respects to NaN. It's popularly implemented as 0x0, but I don't think there's anything preventing it from being implemented as a flag. I say null is similar to NaN because it signifies that a reference refers to nothing. Thus, from a purely objective standpoint, it should be possible to test if a reference is null, but two null references should not compare equal. That this behavior would subtly break a massive amount of code is beside the point :) That said, the ideal behavior of null IMO is this: Foo a, b; a is a // false a is b // false a is null // true a // false !a // true Sean
May 04 2005
parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Sean Kelly" <sean f4.ca> wrote in message 
news:d5as3l$2a40$1 digitaldaemon.com...
 In article <d59tqk$1d9o$1 digitaldaemon.com>, TechnoZeus says...
There are two declarations, because there are two names.
Those two names can have different identities, or they can have the same 
identity.
If they are both null, then they both have the same identity.

I think the confusion stems from the fact that null is a trap value, similar in some respects to NaN. It's popularly implemented as 0x0, but I don't think there's anything preventing it from being implemented as a flag. I say null is similar to NaN because it signifies that a reference refers to nothing.

The invention of 0 (the number) back in ancient history also was capturing the notion of nothing. The whole numbers 1,2,3 were concrete in that you had 1 cow or 2 cows or 3 cows, etc - but what does having 0 cows mean? It was revolutionary and very useful to have this "0" thing. Fast-forward to the computer age and one can argue that "null" is more like "0" than "nan" - besides the fact that in C 0 (the 0-pointer not the number) is null. The rationale for null behaving like other "valid" pointers is like the rationale for 0 behaving like other "valid" number like 1,2,3 etc. It all depends on how one defines "valid".
May 04 2005
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Unknown W. Brackets" <unknown simplemachines.org> wrote in message
news:d56kk2$b3o$1 digitaldaemon.com...
 Where a === b would be... well, a == b.  A comparison of the pointers -
 which tells you if they are pointing to the same data.  Which tells if
 they are the same.

That's right. It just compares the pointers. Nothing else.
May 02 2005
parent Kevin Bealer <Kevin_member pathlink.com> writes:
In article <d56pbi$il5$2 digitaldaemon.com>, Walter says...
"Unknown W. Brackets" <unknown simplemachines.org> wrote in message
news:d56kk2$b3o$1 digitaldaemon.com...
 Where a === b would be... well, a == b.  A comparison of the pointers -
 which tells you if they are pointing to the same data.  Which tells if
 they are the same.

That's right. It just compares the pointers. Nothing else.

If you wanted to avoid this you could make T.init the address of the reference. And it should be just as fast as clearing the pointer, because the address of the pointer is already in a register. If it wasn't, how can you store it? Of course... this could become complicated by "registered" variables ;). if (x === null) becomes if (x == &x). ..Just a (very) idle thought. Kevin
May 04 2005
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <1o3k3k2w9ggm$.1iu7sjnzn0kx2.dlg 40tude.net>, Derek Parnell says...
I think I was under a misapprehension. I thought that we could use the 'is'
operator to tell us if two objects were in fact the same instantiation or
thing. However, this result below surprised me...

  class Foo{}
  Foo a;
  Foo b;

  writefln("a is b: %s", cast(bool)(a is b != 0));
==> Result ...

  a is b: true

But it's pretty clear to me that a is not b. Even though they are both not
instantiated yet, they are still not the same something. Is this supposed
to happen? <rhetorical> If so, should it be explicitly
documented?</rhetorical>

I think null should probably be treated like NaN for identity operations. So 'is' would return 'false' when comparing a null reference to anything including another null reference. Sean
May 02 2005
next sibling parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
 I think null should probably be treated like NaN for identity operations. 
 So
 'is' would return 'false' when comparing a null reference to anything 
 including
 another null reference.

I think nan != nan was decided before the "else" keyword was invented ;-) It would be fun, though, to see what would happen if this were done. Scary, but fun!
May 02 2005
parent Sean Kelly <sean f4.ca> writes:
In article <d56p01$htr$1 digitaldaemon.com>, Ben Hinkle says...
 I think null should probably be treated like NaN for identity operations. 
 So
 'is' would return 'false' when comparing a null reference to anything 
 including
 another null reference.

I think nan != nan was decided before the "else" keyword was invented ;-) It would be fun, though, to see what would happen if this were done. Scary, but fun!

So maybe not a perfect idea :) But it is a tad odd that two null references compare equal. Sean
May 02 2005
prev sibling parent reply "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Sean Kelly" <sean f4.ca> wrote in message
news:d56l7q$c48$1 digitaldaemon.com...
 In article <1o3k3k2w9ggm$.1iu7sjnzn0kx2.dlg 40tude.net>, Derek Parnell says...
I think I was under a misapprehension. I thought that we could use the 'is'
operator to tell us if two objects were in fact the same instantiation or
thing. However, this result below surprised me...

  class Foo{}
  Foo a;
  Foo b;

  writefln("a is b: %s", cast(bool)(a is b != 0));
==> Result ...

  a is b: true

But it's pretty clear to me that a is not b. Even though they are both not
instantiated yet, they are still not the same something. Is this supposed
to happen? <rhetorical> If so, should it be explicitly
documented?</rhetorical>

I think null should probably be treated like NaN for identity operations. So 'is' would return 'false' when comparing a null reference to anything including another null reference. Sean

Yes, that would actually work... but it would also reduce efficiency. That in mind, one has to stop and think about the possible uses of comparing two uninitialized reference types. For example, if the idea was simply to make sure that storing something in "a" and something else in "b" was not going to result in the loss of what was stored in "a" then having "a is b" return false would imply that no such loss will occuur... which is clearly inaccurate information if a is null, regardless of what b is. So, the question then is whether or not the benefits outweigh the losses. The benefit would be having a result that is more intuitive to some people when the identities of two uninitialized reference type items of the same type are compared for equality. The losses would include: Reduced preformance on all identity comparisons where the identities match or either identity is null. Increased potential for unexpected loss of data. Results that would be less intuitive for people who feel that if a in null and b is null then a is b. The need for re-learning what to expect in the identity comparison of uninitiated items. It would appear to me that the losses would outweigh the benefits, so I would not recommend such a change. TechnoZeus TZ
May 04 2005
parent Sean Kelly <sean f4.ca> writes:
In article <d59v84$1eao$1 digitaldaemon.com>, TechnoZeus says...
 I think null should probably be treated like NaN for identity operations.  So
 'is' would return 'false' when comparing a null reference to anything including
 another null reference.

Yes, that would actually work... but it would also reduce efficiency.

The losses would include:
Reduced preformance on all identity comparisons where the identities match or
either identity is null.
Increased potential for unexpected loss of data.
Results that would be less intuitive for people who feel that if a in null and
b is null then a is b.
The need for re-learning what to expect in the identity comparison of
uninitiated items.

It would appear to me that the losses would outweigh the benefits, so I would
not recommend such a change.

I agree. While it may make sense from an academic perspective, I'm not convinced that it's a particularly practical solution. At the very least, it would confuse the heck out of people who had come from... well, nearly any other language. Sean
May 04 2005
prev sibling next sibling parent James McComb <ned jamesmccomb.id.au> writes:
Derek Parnell wrote:

 But it's pretty clear to me that a is not b. Even though they are both not
 instantiated yet, they are still not the same something. Is this supposed
 to happen? <rhetorical> If so, should it be explicitly
 documented?</rhetorical>

It all boils down to this. What should this evaluate to: null is null My (C language) intuitions say that: a is b ...is equivalent to: *a == *b James McComb
May 02 2005
prev sibling next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message
news:1o3k3k2w9ggm$.1iu7sjnzn0kx2.dlg 40tude.net...
 I think I was under a misapprehension. I thought that we could use the

 operator to tell us if two objects were in fact the same instantiation or
 thing.

"That depends on what the meaning of 'is' is." -- Pres. Clinton
May 02 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Walter" <newshound digitalmars.com> wrote in message
news:d56pbh$il5$1 digitaldaemon.com...
 "That depends on what the meaning of 'is' is." -- Pres. Clinton

LOL! :)
May 04 2005
prev sibling next sibling parent "Andrew Fedoniouk" <news terrainformatica.com> writes:
Derek, if you will replace 'is' on '==='
everything will be fine. No aesthetical objections on
null === null .

:)



"Derek Parnell" <derek psych.ward> wrote in message 
news:1o3k3k2w9ggm$.1iu7sjnzn0kx2.dlg 40tude.net...
I think I was under a misapprehension. I thought that we could use the 'is'
 operator to tell us if two objects were in fact the same instantiation or
 thing. However, this result below surprised me...

  class Foo{}
  Foo a;
  Foo b;

  writefln("a is b: %s", cast(bool)(a is b != 0));
 ==> Result ...

  a is b: true

 But it's pretty clear to me that a is not b. Even though they are both not
 instantiated yet, they are still not the same something. Is this supposed
 to happen? <rhetorical> If so, should it be explicitly
 documented?</rhetorical>

 -- 
 Derek Parnell
 Melbourne, Australia
 http://www.dsource.org/projects/build/ v2.05 released 02/May/2005
 http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage
 3/05/2005 10:00:28 AM 

May 02 2005
prev sibling parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message
news:1o3k3k2w9ggm$.1iu7sjnzn0kx2.dlg 40tude.net...
 I think I was under a misapprehension. I thought that we could use the 'is'
 operator to tell us if two objects were in fact the same instantiation or
 thing. However, this result below surprised me...

   class Foo{}
   Foo a;
   Foo b;

   writefln("a is b: %s", cast(bool)(a is b != 0));
 ==> Result ...

   a is b: true

 But it's pretty clear to me that a is not b. Even though they are both not
 instantiated yet, they are still not the same something. Is this supposed
 to happen? <rhetorical> If so, should it be explicitly
 documented?</rhetorical>

 -- 
 Derek Parnell
 Melbourne, Australia
 http://www.dsource.org/projects/build/ v2.05 released 02/May/2005
 http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage
 3/05/2005 10:00:28 AM

I'm not sure how it's implemented in D, but in my experience writing compilers as well as what I know of other compiler implementations in other languages, an item of a reference type which has not had any reference assigned to it, usually is set to point to the address "0" which means that in fact, they all point to the same place until they are told to do otherwise. For the reference type Foo, the statement... Foo x = new Foo; specifies that x is of type Foo, and creates a new instance of type Foo, the address of which is then assigned to the identity of x. On the other hand, if you leave off the "= new Foo" we only have established what type x is, but have in fact not yet given the item a unique identity. In other words, in your example if you could manage assign a value to "a" that value woud also be assigned to "b" because the value "null" is not what a and b are pointing to... but rather what a and b "are". Their identity is null. Their values are undefined... but equal. TechnoZeus
May 04 2005