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

[SR-2162] distance(to:) isn't a proper distance function and frequently leads to bugs in calling code #44770

Open
swift-ci opened this issue Jul 25, 2016 · 0 comments
Labels
improvement standard library Area: Standard library umbrella swift evolution proposal needed Flag → feature: A feature that warrants a Swift evolution proposal

Comments

@swift-ci
Copy link
Contributor

Previous ID SR-2162
Radar None
Original Reporter mattrajca (JIRA User)
Type Improvement
Environment

(Swift 2.x)...

Additional Detail from JIRA
Votes 2
Component/s Standard Library
Labels Improvement, swift-evolution-proposal-needed
Assignee None
Priority Medium

md5: 2968ca3980b3e3f76c373ea465850d66

Issue Description:

A distance function conventionally has the property that d(x,y) ≥ 0. For example, you'd say that the distance between 3 and 5 on a number line is +2, and you'd say the distance between 5 and 3 on a number line is +2 (not -2).

However, if you call Swift's distance(to:) function on an Int, you get signed values depending on the ordering of arguments:

1> 5.distance(to: 3)
$R0: Int = -2
2> 3.distance(to: 5)
$R1: Int = 2

This can be unexpected, and has let to bugs in Apple's open source XCTest implementation. In some robotics code I've been working on, we almost always wrap calls to distance(to:) with abs for this reason, and forgetting a call to abs can lead to serious bugs.

While distance(to:)'s behavior is unexpected and can lead to bugs in calling code, its implementation makes sense given its description in the Strideable protocol:

Returns a stride x such that self.advancedBy(x) approximates other.

For the above to hold for any two integers, distance(to:) has to return negative distances. Unfortunately, using distance in the name also implies it is a proper distance function where in fact it is not.

I see two ways this could be fixed:

1. Change the behavior of distance(to:) to return proper, unsigned distances. This would change the behavior of and break existing code.
2. Rename distance(to:) to offset(to:) or displacement(to:) to clarify it does not actually return an unsigned distance, but a displacement or offset. A fix-it could be provided to help rename and migrate existing code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improvement standard library Area: Standard library umbrella swift evolution proposal needed Flag → feature: A feature that warrants a Swift evolution proposal
Projects
None yet
Development

No branches or pull requests

1 participant