Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix lengthCompare for indexed types #6930

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

Merged
merged 1 commit into from
Jul 18, 2018

Conversation

NthPortal
Copy link
Contributor

No description provided.

@NthPortal NthPortal requested review from julienrf and Ichoran July 12, 2018 22:01
@scala-jenkins scala-jenkins added this to the 2.13.0-M5 milestone Jul 12, 2018
@@ -221,7 +221,7 @@ final class ArrayOps[A](val xs: Array[A]) extends AnyVal {
* x > 0 if this.length > len
* }}}
*/
def lengthCompare(len: Int): Int = xs.length - len
def lengthCompare(len: Int): Int = Integer.compare(xs.length, len)
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer if this reverted to the original behavior (i.e. it returns the difference in lengths) in case anyone is depending on it.

Since we can count on length being non-negative, it could be

val ans = xs.length - len
if (len < 0 && ans < 0) Int.MaxValue else ans

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the default implementation never returned the difference in lengths, though. and if they happen to know it's an IndexedSeq (which is pretty much the only way to even maybe rely on that behaviour), they can just call .length

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 I'm with @NthPortal on this, there is no reason or need to stick to a contract that we never documented. what we documented was to only rely on the sign

Copy link
Contributor

Choose a reason for hiding this comment

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

It's fair enough to say that we didn't agree to obey this contract so we're abandoning it, but I don't think it's hard to preserve it for IndexedSeq, where it worked pretty reliably (Array, ArrayBuffer, String, Vector, etc.). I guess I don't see the downside of supporting it.

/** check that lengthCompare compares values correctly */
@Test def checkLengthCompare(): Unit = {
val test = underTest(size)
assert(lengthCompare(test, Integer.MIN_VALUE) > 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Was this test previously failing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes.

size - Int.MinValue (also, I accidentally used Java's, oops; I'll fix that) is the same as size + Int.MaxValue + 1, which overflows to size + Int.MinValue or Int.MinValue + size. Since size <= Int.MaxValue, Int.MinValue + size <= Int.MinValue + Int.MaxValue == -1. However, size > Int.MinValue, so you ought to get a positive value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(I actually wrote and ran the test before fixing ArrayOps, just to be sure)

@NthPortal NthPortal force-pushed the topic/lengthCompare-fix/PR branch from b0bd461 to 604f8d4 Compare July 13, 2018 13:17
@@ -221,7 +221,7 @@ final class ArrayOps[A](val xs: Array[A]) extends AnyVal {
* x > 0 if this.length > len
* }}}
*/
def lengthCompare(len: Int): Int = xs.length - len
Copy link
Contributor

Choose a reason for hiding this comment

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

what's the scenario where this fails? The test below has Int.MinValue, which seems impossible for a length...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it passes in Int.MinValue as the value of len, which is perfectly possible. See this comment.

Copy link
Contributor

Choose a reason for hiding this comment

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

Well OK, but why would length be negative?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

because someone passed a negative number in ¯\_(ツ)_/¯

Copy link
Contributor

Choose a reason for hiding this comment

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

@isaacl - As a concrete example, suppose you have a collection xs that you will use to pair with any overflow of ys which is normally going to be paired with zs. You might want to know if xs is big enough. So you ask xs.lengthCompare(ys.length - zs.length).

Beyond that, even if we can't think of a sensible use case for a negative value being passed in, it still should return the logically correct result, because we can't always anticipate what someone might try to use it for.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK. Well, this function doesn't feel super useful to me, but I guess if there's no preconditions it should return correctly.

@Ichoran Ichoran dismissed their stale review July 17, 2018 23:24

Requested change is not essential for correctness nor is it universally desired.

@NthPortal
Copy link
Contributor Author

It looks like this is ready for merge

@SethTisue SethTisue merged commit b24a6e0 into scala:2.13.x Jul 18, 2018
@SethTisue
Copy link
Member

thanks Nth!

@NthPortal NthPortal deleted the topic/lengthCompare-fix/PR branch July 18, 2018 05:29
@NthPortal
Copy link
Contributor Author

no problem!

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.

7 participants