Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class PMVector overrides `==` #90

Closed
khinsen opened this issue Feb 20, 2019 · 12 comments

Comments

@khinsen
Copy link

commented Feb 20, 2019

PMVector is the only class in my Pharo image that overrides ProtoObject >> ==, whose comment clearly states that no class should ever override it.

@SergeStinckwich

This comment has been minimized.

Copy link
Member

commented Mar 2, 2019

This is part of DHB original code that was copy-paste in PolyMath, so maybe we have to remove it.

@AtharvaKhare

This comment has been minimized.

Copy link

commented May 8, 2019

Solving this issue only involves removing

{ #category : #comparing }
PMVector >> == aNumber [
"Apply == operator to every element of a vector"
1 to: self size do: [ :n | self at: n put: (self at: n) == aNumber].
]

running tests, and fix tests that dont?

@SergeStinckwich

This comment has been minimized.

Copy link
Member

commented May 8, 2019

Do you understand what is == method ? and why classes should not reimplement it ?

@AtharvaKhare

This comment has been minimized.

Copy link

commented May 8, 2019

My understanding is that == is used to check if two objects pointers refer to the same location (both objects are same) and it is already defined in ProtoObject, there is no reason to override it.

The way PMVector == is implemented, it compares the contents of the object and not the memory location. Renaming it to something like isEqualTo (or =?) would be better.

Am I correct?

@khinsen

This comment has been minimized.

Copy link
Author

commented May 8, 2019

@AtharvaKhare Your analysis is correct, but I'd go farther in the conclusion: overriding == is not only useless but potentially dangerous because it breaks the semantics of the operation.

You suggest renaming it, but do you actually see any situation in which it might be useful? Note that = is already there (inherited from SequenceableCollection), but does something different from PMVector>>==.

@AtharvaKhare

This comment has been minimized.

Copy link

commented May 8, 2019

@khinsen right, I get it :)

Also, looking at the comment and the syntax == aNumber, I think it is intended to apply equality to every element of the vector with a number, so it is not the same as =, which tests for equal contents between objects.
So I think it's use is like this (when rename to something like isEqualTo:

x := #(1 1 1) asPMVector.
x isEqualToThis: 1
>>> a PMVector(true true true)

I also have a question about the API, why do these arithmetic operators (>, <, isEqualTo) modify the object and not return a new one, unlike +, -, * which return new one?

@khinsen

This comment has been minimized.

Copy link
Author

commented May 9, 2019

My question was rather if you see a situation where one might actually want to use it. Why would I ever want to know if all elements of a vector are one-by-one identical? I don't see a good use case, but obviously the author of that code did, so maybe I am just missing it.

@AtharvaKhare

This comment has been minimized.

Copy link

commented May 9, 2019

I can't figure out how it would be useful for PMVector, but in Dataseries, it can be used for converting binary categories to 0-1s.

@khinsen

This comment has been minimized.

Copy link
Author

commented May 13, 2019

Element-by-element comparison yielding a vector/series of booleans are definitely useful in some circumstances. What I don't see is the utility of testing for element-wise object identity. Identity tests a (==) are rarely used. In Pharo I mostly see them as a first step in equality tests, to avoid doing more expensive comparisons. That scenario never happens for elementwise comparison of vectors. So what would be a situation where elementwise identity matters?

@AtharvaKhare

This comment has been minimized.

Copy link

commented May 13, 2019

I got a bit confused between == and = in my previous reply. I can't think of any application that would need ==.

@SergeStinckwich

This comment has been minimized.

Copy link
Member

commented May 13, 2019

== is used everytime you need to be sure objects are unique, for example in a Set. Look at == senders in your image. There are more than 9000 in my image, so this is used a lot of time actually :-)

@SergeStinckwich SergeStinckwich added this to the 1.0 milestone May 13, 2019

@khinsen

This comment has been minimized.

Copy link
Author

commented May 13, 2019

Set uses = for comparing elements, it's IdentitySet that uses ==.

I was a bit surprised by the 9000 senders, so I decided to look at them myself. It's even 12000 in my image, but most of the methods found don't actually use ==. What they do contain instead is ifNil: and/or ifNotNil:. Perhaps the compiler replaces those by == nil. Anyway, I have no idea how to find the real uses of ==. A text search in all methods also finds ==>, comments, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.