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

Stake out a more descriptive definition of equality #3054

Closed
wants to merge 2 commits into from

Conversation

jackfirth
Copy link
Sponsor Contributor

Doesn't tackle eq? yet, but I'm coming for it next.

Follow up to #3019. Questions, comments, suggestions, torches, and pitchforks are all welcome.

Doesn't tackle `eq?` yet, but I'm coming for it next.
reference cycles, they are equal when the infinite unfoldings of the
values would be equal. See also @racket[gen:equal+hash] and
@racket[prop:impersonator-of].
Determines whether @racket[v1] is ``equal to'' @racket[v2], in a manner that
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can improve upon the use of scare quotes. How about "Determines whether v1 and v2 are the same values, in a specific meaning of the word ``same'', captured by the following general properties" and then give the properties. Then go on to discuss how this is actually determined in a per-datatype way (and have a link to the relevant prop for new ones).

depends on the datatype of @racket[v1] and @racket[v2].

Different datatypes have different implementations of @racket[equal?], but the
golden rule uniting them is that @deftech{equal means interchangeable} --- if
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This use of the word "interchangable" is fraught for people with a PL background. Equal? values aren't interchangable in this sense when you get technical.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can this be a “golden rule” if gen:equal+hash doesn’t enforce any of these attributes?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that this is a higher-order property, so it's not really enforce-able at the definition site (you would need a verifier for that, and yet it still won't work for all situations. These problems are in general undecidable). We can imagine dynamically checking some properties like symmetry by, for every call of (equal? a b), calling (equal? b a) to see if they result in the same thing, but that's also prohibitively expensive.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I think it's accurate to say that "equality must be equivalence relation" is a golden rule. Everything breaks otherwise.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think of the golden rule as one that can be broken, but it isn't right Right Thing to break it. :)

That said, it does usually refer to a specific rule so maybe another phrase is better?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“Equal means interchangeable” is a curious phrase, because a) it doesn’t illuminate the meaning of “equal” — it just invokes a different word (“interchangeable”) that is no more concrete, and b) if the essential notion of “equal” is “equivalence relation”, fair enough, but there are plenty of equivalence relations that do not produce intuitively “interchangeable” values (for instance abs)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think another thing that @rfindler was trying to point out regarding "Equal means interchangeable" is that it's technically false. (+ 1 1) is equal? to 2, but they are not interchangeable in some contexts. E.g., (quote (+ 1 1)) and (quote 2).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of something slightly different. I think that the quote thing isn't a big issue as you can just rule out contexts inside quotes. But if you have somewhere (define x (list 1 2)) even if that exact x is in scope, you cannot replace it with (list 1 2) because these can be distinguished (using eq?). But more importantly, I don't think that this kind of thing is really what is important about equal? anyway (I put what I think is important about it in a different comment around here somewhere...)

golden rule uniting them is that @deftech{equal means interchangeable} --- if
two values are @racket[equal?] then it should be possible to substitute one for
the other in a program without breaking the program. Such substitution happens
all the time in real world programs, as many Racket functions use the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of substitution and the use of wrappers here is confusing to me.

true and @racket[(equal? _y _z)] returns true then @racket[(equal? _x _z)]
returns true.}]

Most Racket datatypes implement equality by recursively comparing their
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this paragraph the best. Fundamentally, I think that equal? should be known as an equality relation (three rules just above), it should be known as "open" (in the sense that you can add definitions to it for your own operations) and it should be thought of as roughly "traversing the two objects recursively, looking for subparts that differ". Those seem to me to be the key points of this relation.

Most Racket datatypes implement equality by recursively comparing their
contents: strings compare each of their characters, lists compare each of their
elements, and transparent structures compare each of their fields. This type of
behavior is called @deftech{structural equality}, because two values are equal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This deftech is confusing without other kinds of equality to contrast to.

@samth
Copy link
Sponsor Member

samth commented Apr 13, 2020

What's the current status of this PR?

@jackfirth
Copy link
Sponsor Contributor Author

jackfirth commented Apr 13, 2020 via email

@pmatos
Copy link
Collaborator

pmatos commented Apr 22, 2020

There's an approved review from @mflatt but no merge. What are the actions needed to merge this or close the PR? Maybe if there's still a lot of work to be done, we can close the PR and @jackfirth can reopen upon his return?

This is to avoid many open PRs that are essentially dead-ends.

@rfindler
Copy link
Member

It looks to me like there are several small comments that aren't responded to but that this is close to being ready to merge? (I'm not sure I'm reading things correctly, however.)

@jackfirth
Copy link
Sponsor Contributor Author

@rfindler is correct. There's several small adjustments to make, but not any significant content additions or deletions. I think the adjustments are important and this PR shouldn't be merged without them, so I'm going to close this PR until I come back to it. I've been catching up on racket today so that might be soon, but I'm far too inconsistent of a person to make any promises.

@jackfirth jackfirth closed this Apr 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants