www.digitalmars.com         C & C++   DMDScript  

D - == object.cmp or same object ?

reply Mike Wynn <mike l8night.co.uk> writes:
Yet again I've run foul of the `obj == other` being obj.cmp( other )
not only was `other` null which I would assume is a bit of an odd thing 
to, but I still don't get the reason behind ==/!= treating the object by 
value and not reference.

first, D objects are not C++ references that behave in every other 
respect as Java object, and as `->` === `.` they are C pointers.

second, 90% of my compares are ===/!==

third, its only objects that have two equality comparitors
int a, b => a == b === a === b ?confused yet?

fourth, I hate the subtle difference in visual reprosentation for such a 
huge difference in behaviour.

fifth, whats wrong with a.equals( b ) or *a == *b (could be *a == b or 
$a == b you only need to mark the lhs as being a value not an object, 
which fits with operator cmp (has an object as a param))

is anyone else frustrated by the comparison operators or is it just me 
having a bad day 'cos I can't write
if ( !(v = cast(Var)obj) ) {... }
so change them all to
if ( (v = cast(Var)obj) == null ) {... }
and it fell over and I had to go in search of all my == to see which 
should be === and which should be ==

also
if ( foo === "mark" ) { ... } is almost an error
so if == was as I'd like
if ( foo == "mark" ) { ... } would not be valid
even if you have done foo = "mark"; before as that is relying on 
constant merging (unless that is in the D compiler spec)
even with const char[] MARK = "mark"; if( foo == MARK ) D arrays are not 
const so although foo = MARK is not foo = MARK.dup how often is this used ?
isn't if ( $foo == "mark" ) { ... } more obvious that you are saying
the value of foo is "mark"
or `if ( $foo == fred ) { ... }` if the value of foo is the same as fred
`if ( foo == fred ) { ... }` if foo is fred
Sep 11 2003
next sibling parent Andy Friesen <andy ikagames.com> writes:
Mike Wynn wrote:
 Yet again I've run foul of the `obj == other` being obj.cmp( other )
 not only was `other` null which I would assume is a bit of an odd thing 
 to, but I still don't get the reason behind ==/!= treating the object by 
 value and not reference.

I agree. The simplest solution is to simply remove the overload for == from the Object class, thereby making such a comparison a compile time error. -- andy
Sep 11 2003
prev sibling next sibling parent "Matthew Wilson" <matthew stlsoft.org> writes:
 is anyone else frustrated by the comparison operators or is it just me

I've got an article in this month's CUJ - "Identity and Equality: Syntax and Semantics" - which looks at this issue for C++, C#, D, Java, J#, Python and VB.NET. I was genuinely surprised to realise as I was writing it that C++ and Python were the only two with sensible ways of doing evaluating the identity and equality of variables, with D and Java pretty brain-dead, and C# +vely stupid. (I'm not going to debate it here - my entire argument is in the article.) I've been expecting to be tossed from this ng for the last week, but it appears there are very few CUJ readers that inhabit it. Don't really know whether that's a good or a bad thing overall ...
Sep 12 2003
prev sibling parent reply "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Mike Wynn" <mike l8night.co.uk> ha scritto nel messaggio
news:bjrf0m$1rpd$1 digitaldaemon.com...

(hmmm, this time I'm gonna get shot... :-) )

How about getting rid of === and !== and having a "is" operator which checks
for equality of pointers?

if (a is b) printf("a points to the same object as b\n");

if (a == b) printf("a.eq(b) returned true\n");

Ric
Sep 12 2003
next sibling parent "Matthew Wilson" <dmd synesis.com.au> writes:
 (hmmm, this time I'm gonna get shot... :-) )

 How about getting rid of === and !== and having a "is" operator which

 for equality of pointers?

That's what I would suggest. You'll never get it swallowed, though.
Sep 12 2003
prev sibling next sibling parent reply Mike Wynn <mike l8night.co.uk> writes:
Riccardo De Agostini wrote:
 "Mike Wynn" <mike l8night.co.uk> ha scritto nel messaggio
 news:bjrf0m$1rpd$1 digitaldaemon.com...
 
 (hmmm, this time I'm gonna get shot... :-) )
 
 How about getting rid of === and !== and having a "is" operator which checks
 for equality of pointers?

WHY!! that's what is causings the problems == being .cmp not &a == &b do you realy use == that much ?
 
 if (a is b) printf("a points to the same object as b\n");

if (a == b) printf("a points to the same object as b\n");
 
 if (a == b) printf("a.eq(b) returned true\n");

if (a eq b) printf("a.eq(b) returned true\n");
 
 Ric
 
 

Sep 12 2003
parent reply "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Mike Wynn" <mike l8night.co.uk> ha scritto nel messaggio
news:bjs6pm$2tok$1 digitaldaemon.com...
 Riccardo De Agostini wrote:
 "Mike Wynn" <mike l8night.co.uk> ha scritto nel messaggio
 news:bjrf0m$1rpd$1 digitaldaemon.com...


I'm sorry but I think the problem is not with the meaning of == and !=. I feel they act as they should, i.e. on objects as opposed to pointers. All other operators (with the exception of === and !===, about whom I share your feelings about the excessive visual similarity to == and !=) act on objects; when you write "MyObj a; ++a", you are calling an overloaded operator, not incrementing a pointer. "MyObj a, b; if (a > b)" calls a.cmp(b) and you don't even expect it to compare operators. So why should == and != act differently?
 do you realy use == that much ?

Maybe not. Maybe it's one more reason why I want it to behave coherently with other operators, so I don't have to remember too many rules and exceptions... Also, while it is true that D references are not C++ references, D is not C++ after all. And anyway they are references, not pointers. So applying == to them should compare objects, IMO. Ric
Sep 12 2003
next sibling parent reply "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Riccardo De Agostini" <riccardo.de.agostini email.it> ha scritto nel
messaggio news:bjsb2s$1t3$1 digitaldaemon.com...
 "MyObj a, b; if (a > b)" calls a.cmp(b) and you
 don't even expect it to compare operators.

Should have been "pointers" instead of "operators". No more Chinese food for lunch, I promise. :) Walter (I know you'll be reading this...): don't you think that "is" (as in "if (a is b)") would be better than "===" for pointer equality check? The !== operator might even be eliminated, or maybe substituted by "is_not", "isnot" or something of the kind. This would make things clearer for both C++ experienced programmers (since they wouldn't have to remember which is which between == and ===) and people learning D from scratch or maybe with a Basic/Pascal/whatever background. Ric
Sep 12 2003
parent reply Farmer <itsFarmer. freenet.de> writes:
"Riccardo De Agostini" <riccardo.de.agostini email.it> wrote in
news:bjsbo9$2s5$1 digitaldaemon.com: 

 "Riccardo De Agostini" <riccardo.de.agostini email.it> ha scritto nel
 messaggio news:bjsb2s$1t3$1 digitaldaemon.com...
 "MyObj a, b; if (a > b)" calls a.cmp(b) and you
 don't even expect it to compare operators.

Should have been "pointers" instead of "operators". No more Chinese food for lunch, I promise. :) Walter (I know you'll be reading this...): don't you think that "is" (as in "if (a is b)") would be better than "===" for pointer equality check? The !== operator might even be eliminated, or maybe substituted by "is_not", "isnot" or something of the kind. This would make things clearer for both C++ experienced programmers (since they wouldn't have to remember which is which between == and ===) and people learning D from scratch or maybe with a Basic/Pascal/whatever background. Ric

This wouldn't make things clearer for C++ experienced programmers. They will just write "if (a == b)", because they are a not used to use the operator "is", some won't even know about it.
Sep 12 2003
parent reply "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Farmer" <itsFarmer. freenet.de> ha scritto nel messaggio
news:Xns93F534001C22itsFarmer 63.105.9.61...
 This wouldn't make things clearer for C++ experienced programmers. They
 will just write "if (a == b)", because they are a not used to use the
 operator "is", some won't even know about it.

I assume (though I may be wrong) that an experienced C++ programmer who writes "MyClass a, b; if (a == b)" recognizes a and b as not being pointers, so he/she does not *expect* the == to compare pointers, but to call an overloaded "operator ==". If pointers are to be compared, the experienced C++ programmer (which I also assume to be, first of all, an experienced programmer) starts wordering, so he/she has a good RTFM session (or VTFS, Visit The Fantastic Site!) and discovers the "is" operator. Now it's like that, except that instead of "is" we have the rather confusing (when revising code) "===". Ric
Sep 15 2003
next sibling parent "Matthew Wilson" <matthew stlsoft.org> writes:
is isa better than ===, and so is isa.

:)

"Riccardo De Agostini" <riccardo.de.agostini email.it> wrote in message
news:bk4290$1gi5$3 digitaldaemon.com...
 "Farmer" <itsFarmer. freenet.de> ha scritto nel messaggio
 news:Xns93F534001C22itsFarmer 63.105.9.61...
 This wouldn't make things clearer for C++ experienced programmers. They
 will just write "if (a == b)", because they are a not used to use the
 operator "is", some won't even know about it.

I assume (though I may be wrong) that an experienced C++ programmer who writes "MyClass a, b; if (a == b)" recognizes a and b as not being

 so he/she does not *expect* the == to compare pointers, but to call an
 overloaded "operator ==". If pointers are to be compared, the experienced
 C++ programmer (which I also assume to be, first of all, an experienced
 programmer) starts wordering, so he/she has a good RTFM session (or VTFS,
 Visit The Fantastic Site!) and discovers the "is" operator. Now it's like
 that, except that instead of "is" we have the rather confusing (when
 revising code) "===".

 Ric

Sep 15 2003
prev sibling parent Farmer <itsFarmer. freenet.de> writes:
"Riccardo De Agostini" <riccardo.de.agostini email.it> wrote in
news:bk4290$1gi5$3 digitaldaemon.com: 

 "Farmer" <itsFarmer. freenet.de> ha scritto nel messaggio
 news:Xns93F534001C22itsFarmer 63.105.9.61...
 This wouldn't make things clearer for C++ experienced programmers. They
 will just write "if (a == b)", because they are a not used to use the
 operator "is", some won't even know about it.

I assume (though I may be wrong) that an experienced C++ programmer who writes "MyClass a, b; if (a == b)" recognizes a and b as not being pointers, so he/she does not *expect* the == to compare pointers, but to call an overloaded "operator ==". If pointers are to be compared, the experienced C++ programmer (which I also assume to be, first of all, an experienced programmer) starts wordering, so he/she has a good RTFM session (or VTFS, Visit The Fantastic Site!) and discovers the "is" operator. Now it's like that, except that instead of "is" we have the rather confusing (when revising code) "===". Ric

I'm not sure either, but me and obviously Mike Wynn expect that references behave like pointers when we see "==". Maybe, this is due to our Java experience and experienced C++ programmers with no Java/C# background think differently.
Sep 20 2003
prev sibling next sibling parent Mike Wynn <mike l8night.co.uk> writes:
Riccardo De Agostini wrote:
 "Mike Wynn" <mike l8night.co.uk> ha scritto nel messaggio
 news:bjs6pm$2tok$1 digitaldaemon.com...
 
Riccardo De Agostini wrote:

"Mike Wynn" <mike l8night.co.uk> ha scritto nel messaggio
news:bjrf0m$1rpd$1 digitaldaemon.com...

WHY!! that's what is causings the problems == being .cmp not &a == &b

I'm sorry but I think the problem is not with the meaning of == and !=. I feel they act as they should, i.e. on objects as opposed to pointers. All other operators (with the exception of === and !===, about whom I share your feelings about the excessive visual similarity to == and !=) act on objects; when you write "MyObj a; ++a", you are calling an overloaded operator, not incrementing a pointer. "MyObj a, b; if (a > b)" calls a.cmp(b) and you don't even expect it to compare operators. So why should == and != act differently?

I do accept that a > b would imply the values of a,b and now my chocolate, caffine and nicotine levels are normalised if (a is b) instead of === if looking very good if ( a is null ) { .. } but what for the oposite ? if ( a is !null ) { .. } if ( !(a is null) ) { .. } I think the former is rather too influenced by perl ... unless ( a is null ) { ... }
 
do you realy use == that much ?

Maybe not. Maybe it's one more reason why I want it to behave coherently with other operators, so I don't have to remember too many rules and exceptions...

I'm starting to see that it's ===/== that is winding me up not that == => .cmp and think I agree about the consistancy of == with < currently I find that a === null (&a == null) or != null are my most common comparison on objects &a < &b is very rare
 
 Also, while it is true that D references are not C++ references, D is not
 C++ after all. And anyway they are references, not pointers. So applying ==
 to them should compare objects, IMO.

but `=` (which I still think should be `:=`) assignes the reference not the value my vote has always been a := foo; (a gets shallow copy of foo/ value of a becomes the same as the value of foo) f $= foo; (a now refers to the same things are foo refers to) int func( Obj o ) { o := 9; // not allowed o is not an int or calls operator assign( int ); o $= new Obj( 9 ); // o.k. (same as current `=`) }
Sep 12 2003
prev sibling parent reply Farmer <itsFarmer. freenet.de> writes:
"Riccardo De Agostini" <riccardo.de.agostini email.it> wrote in
news:bjsb2s$1t3$1 digitaldaemon.com: 

 I'm sorry but I think the problem is not with the meaning of == and !=.
 I feel they act as they should, i.e. on objects as opposed to pointers.
 All other operators (with the exception of === and !===, about whom I
 share your feelings about the excessive visual similarity to == and !=)
 act on objects; 

The meaning of == vs === is a big problem. For C++, Java and C# programmers the current semantics poses subtle differences as D references feel more like C++ pointers, Java references or C# references than C++ references. I think the meaning of == vs === should be swapped, it's just too subtle for all those C++ and Java programmers out there. Afterall, the reasons for the current semantics seems not too compelling, to me. Antti Sykari, had brought up some arguments why operator== should mean identity instead of equality: D/12295 Farmer.
Sep 12 2003
next sibling parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
 The meaning of == vs === is a big problem. For C++, Java and C#
 programmers the current semantics poses subtle differences as D references
 feel more like C++ pointers, Java references or C# references than  C++
 references.

Yes ...
 I think the meaning of == vs === should be swapped, it's just too subtle
 for all those C++ and Java programmers out there.

... NO! That would take it even further away from C++ and more towards Java. IMO that would be worse, but even from an unbiased pov it just exchanges one complication for another. We need == (equality), is (identity) and isa (type membership).
 Afterall, the reasons for the current semantics seems not too compelling,
 to me.

 Antti Sykari, had brought up some arguments why operator== should mean
 identity instead of equality:
 D/12295


 Farmer.

Sep 12 2003
next sibling parent reply Patrick Down <Patrick_member pathlink.com> writes:
In article <bjth3u$1n2l$1 digitaldaemon.com>, Matthew Wilson says...
 The meaning of == vs === is a big problem. For C++, Java and C#
 programmers the current semantics poses subtle differences as D references
 feel more like C++ pointers, Java references or C# references than  C++
 references.

Yes ...
 I think the meaning of == vs === should be swapped, it's just too subtle
 for all those C++ and Java programmers out there.

... NO! That would take it even further away from C++ and more towards Java. IMO that would be worse, but even from an unbiased pov it just exchanges one complication for another. We need == (equality), is (identity) and isa (type membership).
 Afterall, the reasons for the current semantics seems not too compelling,
 to me.

 Antti Sykari, had brought up some arguments why operator== should mean
 identity instead of equality:
 D/12295


I'm with Matthew on this one. I think '==' needs to remain a value comparison and '===' should be changed to 'is'. The == and === debates originally happened a while back in this forum. I don't remember the all of the reasons for the choice, but one was for the syntax to remain consistent with the syntax for arrays. We wanted the comparison operators to do element by element comparisons on arrays. This is why you can do convenient things like if(foo <= "fred") in D now. == was made a value comparison to remain consistent with the other comparison operators. It also made sense for the array and object syntax to be consistent also so == was used as a value comparison for objects too. === was chosen to be the identity comparison and as stated above I'd much prefer it to be 'is'. I think a number of issues with == would go away if it was implemented like this. if(a === b) return true; else if(a === null) return false; else if(b === null) return false; else // If a has an eq return a.eq(b);
Sep 12 2003
next sibling parent reply Mike Wynn <mike l8night.co.uk> writes:
Patrick Down wrote:
 In article <bjth3u$1n2l$1 digitaldaemon.com>, Matthew Wilson says...
 
The meaning of == vs === is a big problem. For C++, Java and C#
programmers the current semantics poses subtle differences as D references
feel more like C++ pointers, Java references or C# references than  C++
references.

Yes ...
I think the meaning of == vs === should be swapped, it's just too subtle
for all those C++ and Java programmers out there.

... NO! That would take it even further away from C++ and more towards Java. IMO that would be worse, but even from an unbiased pov it just exchanges one complication for another. We need == (equality), is (identity) and isa (type membership).
Afterall, the reasons for the current semantics seems not too compelling,
to me.

Antti Sykari, had brought up some arguments why operator== should mean
identity instead of equality:
D/12295


I'm with Matthew on this one. I think '==' needs to remain a value comparison and '===' should be changed to 'is'. The == and === debates originally happened a while back in this forum. I don't remember the all of the reasons for the choice, but one was for the syntax to remain consistent with the syntax for arrays. We wanted the comparison operators to do element by element comparisons on arrays. This is why you can do convenient things like if(foo <= "fred") in D now. == was made a value comparison to remain consistent with the other comparison operators. It also made sense for the array and object syntax to be consistent also so == was used as a value comparison for objects too. === was chosen to be the identity comparison and as stated above I'd much prefer it to be 'is'. I think a number of issues with == would go away if it was implemented like this. if(a === b) return true; else if(a === null) return false; else if(b === null) return false; else // If a has an eq return a.eq(b);

so ( a == null ) would always be false ?
Sep 12 2003
next sibling parent Mike Wynn <mike l8night.co.uk> writes:
 I think a number of issues with == would go away if it was
 implemented like this.

 if(a === b)
 return true;
 else if(a === null)
 return false;
 else if(b === null)
 return false;
 else // If a has an eq
 return a.eq(b);

so ( a == null ) would always be false ?

that is exactly what is needed a == null equiv to a === null assuming a != b is defined as !(a == b) that works too
Sep 12 2003
prev sibling parent "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Mike Wynn" <mike l8night.co.uk> ha scritto nel messaggio
news:bjtm1j$1tfk$2 digitaldaemon.com...
 so ( a == null ) would always be false ?

"(a == null)" does not even make sense, IMHO. It should be "(a === null)", if checking for an unassigned reference was what you intended. "(a is null)" would be better, but the current compiler (still) has "==="... Ric
Sep 15 2003
prev sibling next sibling parent reply Mike Wynn <mike l8night.co.uk> writes:
Patrick Down wrote:
 In article <bjth3u$1n2l$1 digitaldaemon.com>, Matthew Wilson says...
 
The meaning of == vs === is a big problem. For C++, Java and C#
programmers the current semantics poses subtle differences as D references
feel more like C++ pointers, Java references or C# references than  C++
references.

Yes ...
I think the meaning of == vs === should be swapped, it's just too subtle
for all those C++ and Java programmers out there.

... NO! That would take it even further away from C++ and more towards Java. IMO that would be worse, but even from an unbiased pov it just exchanges one complication for another. We need == (equality), is (identity) and isa (type membership).
Afterall, the reasons for the current semantics seems not too compelling,
to me.

Antti Sykari, had brought up some arguments why operator== should mean
identity instead of equality:
D/12295


I'm with Matthew on this one. I think '==' needs to remain a value comparison and '===' should be changed to 'is'. The == and === debates originally happened a while back in this forum. I don't remember the all of the reasons for the choice, but one was for the syntax to remain consistent with the syntax for arrays. We wanted the comparison operators to do element by element comparisons on arrays. This is why you can do convenient things like if(foo <= "fred") in D now. == was made a value comparison to remain consistent with the other comparison operators. It also made sense for the array and object syntax to be consistent also so == was used as a value comparison for objects too. === was chosen to be the identity comparison and as stated above I'd much prefer it to be 'is'. I think a number of issues with == would go away if it was implemented like this. if(a === b) return true; else if(a === null) return false; else if(b === null) return false; else // If a has an eq return a.eq(b);

cases when you do want to compare that two objects are the same object would have to be ( &a == &b ) which is more visually obvious.
Sep 12 2003
next sibling parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
"Mike Wynn" <mike l8night.co.uk> wrote in message
news:bjtmft$1ub4$1 digitaldaemon.com...
 if == was implemented as that I believe ===/!== can be dropped the rare
 cases when you do want to compare that two objects are the same object
 would have to be ( &a == &b ) which is more visually obvious.

I would like this better. If you want to compare addresses, compare addresses... there is an address-of operator in D. We need to be able to overload at least the < operator so we can control sorting order etc. Sean
Sep 13 2003
parent reply Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <bjvljt$1m5i$1 digitaldaemon.com>, Sean L. Palmer wrote:
 "Mike Wynn" <mike l8night.co.uk> wrote in message
 news:bjtmft$1ub4$1 digitaldaemon.com...
 if == was implemented as that I believe ===/!== can be dropped the rare
 cases when you do want to compare that two objects are the same object
 would have to be ( &a == &b ) which is more visually obvious.

I would like this better. If you want to compare addresses, compare addresses... there is an address-of operator in D.

Which brings us the problem that we should treat objects the same as structs. But we cannot, because we don't know their actual size beforehand and therefore cannot put them on the stack. So class objects remain, practically, pointers. And taking a pointer of the object would be like taking an address of a smart pointer class in C++. Which one wouldn't under normal circumstances do. It's funny, I never really thought it was legal to take an address of an object, but it works: void main() { Object o1 = new Object; Object o2 = o1; printf("o1 == %08x, o2 == %08x, &o1 == %08x, &o2 == %08x\n", o1, o2, &o1, &o2); } o1 == 00870fd0, o2 == 00870fd0, &o1 == 0012ff30, &o2 == 0012ff34 So &o1 !== &o2 but o1 != o2. In fact, &o1 == &o2 implies o1 === o2, which in turn implies o1 == o2. (Well, except if o1 is null, in which case the comparison crashes. So much for the fine theory) And &o1 == &o2 in fact is true only if it's the same variable. -Antti
Sep 13 2003
parent reply Mike Wynn <mike l8night.co.uk> writes:
Antti Sykäri wrote:
 In article <bjvljt$1m5i$1 digitaldaemon.com>, Sean L. Palmer wrote:
 
"Mike Wynn" <mike l8night.co.uk> wrote in message
news:bjtmft$1ub4$1 digitaldaemon.com...

if == was implemented as that I believe ===/!== can be dropped the rare
cases when you do want to compare that two objects are the same object
would have to be ( &a == &b ) which is more visually obvious.

I would like this better. If you want to compare addresses, compare addresses... there is an address-of operator in D.

Which brings us the problem that we should treat objects the same as structs. But we cannot, because we don't know their actual size beforehand and therefore cannot put them on the stack. So class objects remain, practically, pointers. And taking a pointer of the object would be like taking an address of a smart pointer class in C++. Which one wouldn't under normal circumstances do. It's funny, I never really thought it was legal to take an address of an object, but it works: void main() { Object o1 = new Object; Object o2 = o1; printf("o1 == %08x, o2 == %08x, &o1 == %08x, &o2 == %08x\n", o1, o2, &o1, &o2); } o1 == 00870fd0, o2 == 00870fd0, &o1 == 0012ff30, &o2 == 0012ff34 So &o1 !== &o2 but o1 != o2. In fact, &o1 == &o2 implies o1 === o2, which in turn implies o1 == o2. (Well, except if o1 is null, in which case the comparison crashes. So much for the fine theory) And &o1 == &o2 in fact is true only if it's the same variable. -Antti

your right ... currently &o is (void*)o so what I wrote as ( &a == &b ) is infact ( cast(void*)a == cast(void*)b )
Sep 13 2003
parent Mike Wynn <mike l8night.co.uk> writes:
Mike Wynn wrote:
 Antti Sykäri wrote:
 
 In article <bjvljt$1m5i$1 digitaldaemon.com>, Sean L. Palmer wrote:

 "Mike Wynn" <mike l8night.co.uk> wrote in message
 news:bjtmft$1ub4$1 digitaldaemon.com...

 if == was implemented as that I believe ===/!== can be dropped the rare
 cases when you do want to compare that two objects are the same object
 would have to be ( &a == &b ) which is more visually obvious.

I would like this better. If you want to compare addresses, compare addresses... there is an address-of operator in D.

Which brings us the problem that we should treat objects the same as structs. But we cannot, because we don't know their actual size beforehand and therefore cannot put them on the stack. So class objects remain, practically, pointers. And taking a pointer of the object would be like taking an address of a smart pointer class in C++. Which one wouldn't under normal circumstances do. It's funny, I never really thought it was legal to take an address of an object, but it works: void main() { Object o1 = new Object; Object o2 = o1; printf("o1 == %08x, o2 == %08x, &o1 == %08x, &o2 == %08x\n", o1, o2, &o1, &o2); } o1 == 00870fd0, o2 == 00870fd0, &o1 == 0012ff30, &o2 == 0012ff34 So &o1 !== &o2 but o1 != o2. In fact, &o1 == &o2 implies o1 === o2, which in turn implies o1 == o2. (Well, except if o1 is null, in which case the comparison crashes. So much for the fine theory) And &o1 == &o2 in fact is true only if it's the same variable. -Antti

your right ... currently &o is (void*)o so what I wrote as ( &a == &b ) is infact ( cast(void*)a == cast(void*)b )

what I mean is what I wrote as &a is the same as the current cast(void*) &a currently means address of the variable as D objects are not references but pointers. oj reflection Obj a; Obj * f = &a; //<= means that (&a == &b) will only be true is a is b! so I guess === and !== have to stay unless a new object operator is introduce to cast the object to a `void*` or $ seem likely ( a == b ) => ( cast(void*)a === cast(void*)b )
Sep 13 2003
prev sibling parent "Philippe Mori" <philippe_mori hotmail.com> writes:
 I'm with Matthew on this one.  I think '==' needs to remain a value
 comparison and '===' should be changed to 'is'.

 The == and === debates originally happened a while back
 in this forum.  I don't remember the all of the reasons
 for the choice,  but one was for the syntax to remain consistent
 with the syntax for arrays.  We wanted the comparison operators
 to do element by element comparisons on arrays.  This is why you
 can do convenient things like if(foo <= "fred") in D now.  == was
 made a value comparison to remain consistent with the other
 comparison operators.  It also made sense for the array and
 object syntax to be consistent also so == was used as a value
 comparison for objects too.  === was chosen to be the identity
 comparison and as stated above I'd much prefer it to be 'is'.

 I think a number of issues with == would go away if it was
 implemented like this.

 if(a === b)
 return true;
 else if(a === null)
 return false;
 else if(b === null)
 return false;
 else // If a has an eq
 return a.eq(b);

cases when you do want to compare that two objects are the same object would have to be ( &a == &b ) which is more visually obvious.

I think that == should compare object without checking for null and we should have another operator for "safe" comparison. That way it will be efficient for those cases where we know that object should not be nil... But maybe a better solution would be to have ref modifier for references and the compiler optimize the full comparison above when he knows that either one or both arguments are not null... (not that the compiler would be able to suppose ref for local declaration that are known to bo non-null and cannot be modified externally). Note that the compiler might assumes reference if we called member function of the object... And we could uses a ref operator (ref, * or are some suggestions) when we want to tell the compile to assume valid reference Something like: a == b // full comparision *a == *b // compare values *a == b // returns false if b is null; otherwise value comparison. &a == &b // compare address And using an operator to tell that we have a reference allows to check for null only on one side if the other size is known to be non null. Alternatively, we can do values comparison by default and have a modifier for full comparison: a == b // values comparison a == b // full comparision a == b // returns false if a is null; otherwise values comparision I would also prefer := for assignment as in Pascal and Delphi. This will essentially solve the problem of misusing = for == when we one to compare object and it would allows uses to have assignment in a condition without risk... if (a == b) { } // compare a et b if (a := b) { } // assign b to a and check a And we will have another operator for reference assignment a := b; // value assignment a $= b; // ref assignment (or maybe =)
Sep 15 2003
prev sibling parent "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Patrick Down" <Patrick_member pathlink.com> ha scritto nel messaggio
news:bjtltk$1thb$1 digitaldaemon.com...
 I think a number of issues with == would go away if it was
 implemented like this.

 if(a === b)
 return true;
 else if(a === null)
 return false;
 else if(b === null)
 return false;
 else // If a has an eq
 return a.eq(b);

This seems very odd to me. A language that implements design by contract should not implicitly allow this kind of defensive programming. In other words, if "a + null" bombs, "a == null" should bomb, too. "==", when applied to references, is just an overloaded operator. What if you have "a == b" and b is null because of a programming error? I expect the expression to explode into microscopic pieces when evaluated, not just to return false. If you wanted that to be valid only when null is specified as a constant, what's wrong in "a is null"? Ric
Sep 15 2003
prev sibling next sibling parent "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Matthew Wilson" <matthew stlsoft.org> ha scritto nel messaggio
news:bjth3u$1n2l$1 digitaldaemon.com...
 We need == (equality), is (identity) and isa (type membership).

I agree 100% on all three (although it was needless to say for the first two...) Ric
Sep 15 2003
prev sibling parent Farmer <itsFarmer. freenet.de> writes:
"Matthew Wilson" <matthew stlsoft.org> wrote in 
news:bjth3u$1n2l$1 digitaldaemon.com:

 I think the meaning of == vs === should be swapped, it's just too subtle
 for all those C++ and Java programmers out there.

... NO! That would take it even further away from C++ and more towards Java. IMO that would be worse, but even from an unbiased pov it just exchanges one complication for another.

You're right. It doesn't solve the problem but merely moves it to another corner. Personally, I can't remember that I have ever used the equals() function in Java - Okay, maybe for java.lang.String. But I need the identity operator quite often. Farmer.
Sep 20 2003
prev sibling parent reply "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Farmer" <itsFarmer. freenet.de> ha scritto nel messaggio
news:Xns93F5249FA35FitsFarmer 63.105.9.61...
 The meaning of == vs === is a big problem. For C++, Java and C#
 programmers the current semantics poses subtle differences as D references
 feel more like C++ pointers, Java references or C# references than  C++
 references.

IMHO == should mean equality when applied to references, just as + does not sum addresses as long as you don't apply it to pointers. It seems more logical to me. Furthermore, as you admit, D references resemble Java references and C# references. I'd add Delphi references and VB references to the list. Now, why should the semantics of ==, as applied to references, be changed to make it more similar to what C++ lets you do with pointers, in a language where references have a different meaning from C++? Ric
Sep 15 2003
next sibling parent reply Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <bk4292$1gi5$4 digitaldaemon.com>, Riccardo De Agostini wrote:
 "Farmer" <itsFarmer. freenet.de> ha scritto nel messaggio
 news:Xns93F5249FA35FitsFarmer 63.105.9.61...
 The meaning of == vs === is a big problem. For C++, Java and C#
 programmers the current semantics poses subtle differences as D references
 feel more like C++ pointers, Java references or C# references than  C++
 references.

Furthermore, as you admit, D references resemble Java references and C# references. I'd add Delphi references and VB references to the list. Now, why should the semantics of ==, as applied to references, be changed to make it more similar to what C++ lets you do with pointers, in a language where references have a different meaning from C++?

Because of consistency with what the operator "=" does. I pointed out in a post a few months ago that the semantics of operator "=" (assignment) should IMHO resemble those of operator "==" (equality). In D, operator "=" works as if it operated on pointers, and operator "==" works as if it operated on the actual objects. In addition, equivalence can be overloaded, but assignment to my knowledge cannot. I would say that either operator "==" and operator "=" should work as if on pointers or as if on the actual values (in which case both should be overloadable). But not so that one does one thing and the other does something else. Maybe I'm just too academic, seeking symmetry wherever I go. Admittedly, this is just a small detail in the big picture, and maybe the real world experience shows that things in fact should be as they are as they are now. -Antti
Sep 15 2003
parent "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Antti Sykäri" <jsykari gamma.hut.fi> ha scritto nel messaggio
news:slrnbmbhho.lf.jsykari pulu.hut.fi...
 Because of consistency with what the operator "=" does.

While I don't agree completely, at least your answer is about the language itself, with no "Language X** does it, so it must be the right way" issues.
 I would say that either operator "==" and operator "=" should work as if
 on pointers or as if on the actual values (in which case both should be
 overloadable).

So, since all other operators operate on the actual objects, "=" should, too. That's a good point, per se; but how do you initialize a reference, let alone copy it? We'd need another operator: MyClass a, b; a <- b; // Copy the reference so "a" and "b" reference the same object a = b; // Copy the object and make "a" a reference to the copy Ric
Sep 15 2003
prev sibling parent reply Farmer <itsFarmer. freenet.de> writes:
"Riccardo De Agostini" <riccardo.de.agostini email.it> wrote in
news:bk4292$1gi5$4 digitaldaemon.com: 

[snip]
 Furthermore, as you admit, D references resemble Java references and C#
 references. I'd add Delphi references and VB references to the list.
 Now, why should the semantics of ==, as applied to references, be
 changed to make it more similar to what C++ lets you do with pointers,
 in a language where references have a different meaning from C++?
 
 Ric
 

Consider that Java references act like pointers: if (object == null) //D meaning: if (object === null) if (object.equals(objectB)) //D meaning: if (object == objectB) C# is actually quite special. In essence it's evaluated like Patrick Down proposes right in this thread: if(a === b) return true; else if(a === null) return false; else if(b === null) return false; else // If a has an eq return a.eq(b); But that means that C# programmers are also used to write: if (object != null) I don't know how Delphi references work, but I guess like C# references. Farmer
Sep 20 2003
parent reply "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Farmer" <itsFarmer. freenet.de> ha scritto nel messaggio
news:Xns93FD4B286B3FitsFarmer 63.105.9.61...
 Consider that Java references act like pointers:

 if (object == null)            //D meaning: if (object === null)
 if (object.equals(objectB))    //D meaning: if (object == objectB)

I actually should be more careful when talking about languages I don't know. :-) Anyway, this looks more like a C++'ism forced into Java than a "real" language feature to me.
 C# is actually quite special.
 [...]
 But that means that C# programmers are also used to write:
 if (object != null)

...but then does C# have pointers at all?
 I don't know how Delphi references work, but I guess like C# references.

I admit that Delphi references do work like Java references in this context, i.e. pointers are compared by the "=" operator. But Delphi has no operator overloading, so there can be no ambiguity. Visual Basic, which has no pointers, has a "Is" operator to compare references and, being there no operator overloading either, it obviously compares pointers (yeah, where did you think the "is" operator idea came from? My own little brain? No way ;-) ) This one, to me at least, looks like the most elegant solution with regard to readability, and VB implements it even if there would be no risk of ambiguity. Yes, I know that _real_ programmers don't use VB... ;-) Ric --- Real programmers use COPY CON: <program_name>.EXE
Sep 22 2003
parent reply Farmer <itsFarmer. freenet.de> writes:
"Riccardo De Agostini" <riccardo.de.agostini email.it> wrote in
news:bkm6lt$30gp$1 digitaldaemon.com: 

 "Farmer" <itsFarmer. freenet.de> ha scritto nel messaggio
 news:Xns93FD4B286B3FitsFarmer 63.105.9.61...
 Consider that Java references act like pointers:

 if (object == null)            //D meaning: if (object === null)
 if (object.equals(objectB))    //D meaning: if (object == objectB)

I actually should be more careful when talking about languages I don't know. :-) Anyway, this looks more like a C++'ism forced into Java than a "real" language feature to me.

Did I hear you say "I actually should be more careful when talking about languages I don't know." just one sentence before?
 
 C# is actually quite special.
 [...]
 But that means that C# programmers are also used to write:
 if (object != null)

...but then does C# have pointers at all?

Yes, C pointers are supported. Except when running in Java style "sand-box" mode ;-)
 I don't know how Delphi references work, but I guess like C#
 references. 

I admit that Delphi references do work like Java references in this context, i.e. pointers are compared by the "=" operator. But Delphi has no operator overloading, so there can be no ambiguity.

I heard from someone (Ilya?) in this NG that the latest versions of Delphi have operator overloading.
 Visual Basic, which has no pointers, has a "Is" operator to compare
 references and, being there no operator overloading either, it obviously
 compares pointers (yeah, where did you think the "is" operator idea came
 from? My own little brain? No way ;-) ) This one, to me at least, looks
 like the most elegant solution with regard to readability, and VB
 implements it even if there would be no risk of ambiguity.
 Yes, I know that _real_ programmers don't use VB... ;-)

Must agree, at least with the last sentence :-D Farmer.
 
 Ric
 
 --- Real programmers use COPY CON: <program_name>.EXE
 
 

Sep 22 2003
parent "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Farmer" <itsFarmer. freenet.de> ha scritto nel messaggio
news:Xns93FFB31D37CFitsFarmer 63.105.9.61...
 "Riccardo De Agostini" <riccardo.de.agostini email.it> wrote in
 news:bkm6lt$30gp$1 digitaldaemon.com:

 Did I hear you say "I actually should be more careful when talking about
 languages I don't know." just one sentence before?

Yes, as long as you have a text-to-speech app running. :-) All right, I don't know Java. I feel, nonetheless, that comparing two object references for equality via the == operator, at least in a language like D which offers the possibility of overloading it, should mean comparing the objects and not their pointers. All the discussion started from the meaning of == and === in D, so I gave my 2 cents. Maybe I tried adding a third cent but my pocket was empty... I apologize for that. I still am strongly convinced that, as long as "a < b" invokes the "eq" method, "a == b" should, too. D went the right way IMO by separating "==" and "===". Since "===" is visually similar to "==" to the point of becoming confusing, I proposed using "is" instead of "==="; not because VB has it, just because it seems logical and readable to me. It could come from VB, Javascript, Logo, AutoLISP, or from Latin grammar and I could not care less. If I sounded rude, that was out of my intention. Sometimes my English goes out of control. :)
 Yes, C pointers are supported. Except when running in Java style
 "sand-box" mode ;-)

So, as far as I understand, the "==" remains the only "universal" C# way to check for object pointer equality, doesn't it?
 Yes, I know that _real_ programmers don't use VB... ;-)

Must agree, at least with the last sentence :-D

There's a reason for that. Even more than one. I could tell you at least one story which will make you wonder if VB was actually written by real compiler authors... (Mr. Gates, how about firing whoever implemented the VB preprocessor and hiring Walter instead?) Ric
Sep 23 2003
prev sibling next sibling parent Andy Friesen <andy ikagames.com> writes:
Riccardo De Agostini wrote:
 "Mike Wynn" <mike l8night.co.uk> ha scritto nel messaggio
 news:bjrf0m$1rpd$1 digitaldaemon.com...
 
 (hmmm, this time I'm gonna get shot... :-) )
 
 How about getting rid of === and !== and having a "is" operator which checks
 for equality of pointers?
 
 if (a is b) printf("a points to the same object as b\n");
 
 if (a == b) printf("a.eq(b) returned true\n");
 
 Ric

I like this syntax a lot. Python uses 'is' and 'is not' to test object identity, which is about as readable as it gets. -- andy
Sep 12 2003
prev sibling parent reply Derek Parnell <Derek.Parnell No.Spam> writes:
On Fri, 12 Sep 2003 11:18:25 +0200 (09/12/03 19:18:25)
, Riccardo De Agostini <riccardo.de.agostini email.it> wrote:

 "Mike Wynn" <mike l8night.co.uk> ha scritto nel messaggio
 news:bjrf0m$1rpd$1 digitaldaemon.com...

 (hmmm, this time I'm gonna get shot... :-) )

 How about getting rid of === and !== and having a "is" operator which 
 checks
 for equality of pointers?

 if (a is b) printf("a points to the same object as b\n");

 if (a == b) printf("a.eq(b) returned true\n");

 Ric

Don't be silly, Riccardo. That would make code more readible and give us less opportunities to have debug session. -- Derek
Sep 14 2003
next sibling parent "Matthew Wilson" <matthew stlsoft.org> writes:
<G>

"Derek Parnell" <Derek.Parnell No.Spam> wrote in message
news:oprvilbpcryj5swd news.digitalmars.com...
 On Fri, 12 Sep 2003 11:18:25 +0200 (09/12/03 19:18:25)
 , Riccardo De Agostini <riccardo.de.agostini email.it> wrote:

 "Mike Wynn" <mike l8night.co.uk> ha scritto nel messaggio
 news:bjrf0m$1rpd$1 digitaldaemon.com...

 (hmmm, this time I'm gonna get shot... :-) )

 How about getting rid of === and !== and having a "is" operator which
 checks
 for equality of pointers?

 if (a is b) printf("a points to the same object as b\n");

 if (a == b) printf("a.eq(b) returned true\n");

 Ric

Don't be silly, Riccardo. That would make code more readible and give us less opportunities to have debug session. -- Derek

Sep 14 2003
prev sibling parent reply "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Derek Parnell" <Derek.Parnell No.Spam> ha scritto nel messaggio
news:oprvilbpcryj5swd news.digitalmars.com...
 Don't be silly, Riccardo. That would make code more readible and give us
 less opportunities to have debug session.

Aw, sorry, I forgot about _that_! :) Hoping to be forgiven, I'll propose a "resembles" operator, which returns true if the pointers to two objects differ by less than a random quantity. (Please Matthew, don't write on CUJ about this, or D is dead). Ric
Sep 15 2003
next sibling parent "Matthew Wilson" <matthew stlsoft.org> writes:
 Aw, sorry, I forgot about _that_! :)

 Hoping to be forgiven, I'll propose a "resembles" operator, which returns
 true if the pointers to two objects differ by less than a random quantity.

LOL
 (Please Matthew, don't write on CUJ about this, or D is dead).

I promise. :)
Sep 15 2003
prev sibling parent reply Andy Friesen <andy ikagames.com> writes:
Riccardo De Agostini wrote:
 "Derek Parnell" <Derek.Parnell No.Spam> ha scritto nel messaggio
 news:oprvilbpcryj5swd news.digitalmars.com...
 
Don't be silly, Riccardo. That would make code more readible and give us
less opportunities to have debug session.

Aw, sorry, I forgot about _that_! :) Hoping to be forgiven, I'll propose a "resembles" operator, which returns true if the pointers to two objects differ by less than a random quantity. (Please Matthew, don't write on CUJ about this, or D is dead). Ric

How about "was a". (which, logically, would erase both pointers, and return true if they were equal to some value (not necessarily each other)) -- andy
Sep 15 2003
parent "Riccardo De Agostini" <riccardo.de.agostini email.it> writes:
"Andy Friesen" <andy ikagames.com> ha scritto nel messaggio
news:bk4ec3$20co$1 digitaldaemon.com...
 How about "was a". (which, logically, would erase both pointers, and
 return true if they were equal to some value (not necessarily each other))

:-) With a little more help by the compiler, even a "is_likely_to_become", which checks for assignments to a reference in the next thirty lines of code or so, wouldn't hurt either... Ric
Sep 15 2003