Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add support for Iterable to sizeIs#11047

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
wernerschram wants to merge1 commit intoscala:2.13.x
base:2.13.x
Choose a base branch
Loading
fromwernerschram:2.13.x

Conversation

wernerschram
Copy link

This allows thesizeIs function to also cover thesizeCompare(Iterable[_]) variation.

The main motivation for adding this is thatsizeIs currently returns an unintuitive result when used in the formcol1.sizeIs == col2.sizeIs. This notation is not documented and likely not intended, but it is valid and it feels intuitive that it should result in comparing the size of the two collections.

The reason for that is thatcol1.sizeIs == 5 is the functional equivalent ofcol1.size == 5 and callscol1.sizeCompare(5) == 0. Given thatsizeCompare has a second implementation:sizeCompare(Iterable[_]), I would expect thatcol1.sizeIs == col2.sizeIs would be the functional equivalent tocol1.size == col2.size and callcol1.sizeCompare(col2) == 0. The problem is that the syntaxcol1.sizeIs == col2.sizeIs is valid, but this is becausecol1.sizeIs returns a value class for col1. This causes the== operator to be handled byAny.==() which calls theequals method for the collections.

So the result doesn't represent the equality of the sizes of the collections, but the equality of the collections itself. So currentlySeq(1,2).sizeIs == Seq(2,3).sizeIs results infalse.

NthPortal, lrytz, and ansvonwa reacted with heart emoji
@scala-jenkinsscala-jenkins added this to the2.13.17 milestoneApr 16, 2025
@SethTisue
Copy link
Member

@scala/collections@NthPortal

NthPortal reacted with heart emoji

@SethTisueSethTisue added library:not-forward-bincompat library:collectionsPRs involving changes to the standard collection library labelsApr 17, 2025
@NthPortal
Copy link
Contributor

NthPortal commentedApr 17, 2025
edited
Loading

the problem is,col1.sizeIs == col2.sizeIs is semantically awful/nonsensical in English (the language of the Scala stdlib API).

sizeIs already stretches English semantics. take for example,col.size < 4—that code reads as "col's size is less than 4". consequently,< in that snippet means "is less than". if we then consider the equivalent code withsizeIs, we would havecol.sizeIs < 4, which consequently reads as "col's sizeis is less than 4". thankfully, we tend to have no problem dropping the "is" from the reading of< (and all the other comparison operators), so we can instead read it as "col's size is less than 4".

this does not work when comparing two collections. if we take your example ofcol1.sizeIs == col2.sizeIs, that reads as "col1's size is equal tocol2's size is", which just doesn't work in English.

if you can come up with an API that reads fine as prose in English, I would love to add it, but the best I've ever been able to come up with iscol1.sizeIs <_sizeOf(col2), which is an ugly method name with an underscore in the middle which we in general strongly do not like. I agree that it's a gap in the API, but I have found no good solution and unfortunately I am not in favour of this particular one.


Personally, I sometimes readif (x < 5) as "ifx less than 5" rather than "ifxis less than 5", so it feels quite natural to me at least

@SethTisue
Copy link
Member

SethTisue commentedApr 17, 2025
edited
Loading

Hmm. Perhaps we could provide a different way to do this that reads better, but since universal equality means we have no way of preventingcol1.sizeIs == col2.sizeIs from being legal, shouldn't it behave sensibly?

@lrytz
Copy link
Member

lrytz commentedApr 17, 2025
edited
Loading

Mhm.. MaybesizeIs should have been calledsizeComp. That name would not attempt to be English language as much, and also make the connection tosizeCompare more obvious.

@wernerschram
Copy link
Author

Tough one. I think that ideally the name should convey that you can use it to compare the size without actually calculating it, to distinguish it fromsize.

PerhapsdeferredSize:col1.deferredSize == col2.deferredSize, so it reads "col1s deferred size equals col2s deferred size", so it emphasizes the fact that the size isn't necessarily calculated to evaluate the result.

@SethTisue
Copy link
Member

orlazySize?

I'm not sure it's actually worth changing, though, given that thesizeIs == sizeIs case is unusual. we could document as it working (once it does) and just mention/acknowledge in the doc that it reads strangely?

ansvonwa reacted with thumbs up emoji

@NthPortal
Copy link
Contributor

NthPortal commentedApr 24, 2025
edited
Loading

we could document as it working (once it does)

I don't actually think we should change the behaviour ofa.sizeIs == b.sizeIs—I think it's an ugly API, and even if we add a deprecated override, having them compare as equal just for being the same size just encourages people to use it and suppress the deprecation warning. I'd rather it not even compile, though I don't think we have an annotation for that.

MaybesizeIs should have been calledsizeComp

I disagree with this. there is a strong API correspondence with theOrdered API, and I think breaking that correspondence would be a mistake.

a.size.compare(b.size)<-> a.sizeCompare(b)a.size.compare(4)<-> a.sizeCompare(4)(a.size<4)<-> (a.sizeIs<4)

calling itsizeComp would muddy that correspondence by putting its name in between the different operations:

a.size.compare(4)<-> a.sizeCompare(4)(a.size<4)<-> (a.sizeComp<4)

I've been thinking about this a lot, and had a thought: there's a discrepancy in the#sizeCompare(Iterable[_]), API, and I'm wondering if we might use it as the basis for expanding the API. consider the following:

a.size.compare(b.size)<-> a.sizeCompare(b)

there are two ways to think ofsizeCompare here: as a contraction ofsize.compare, or as a special type of comparison operation calledsizeCompare. if we read it as the former, then there is a discrepancy in thatsize is missing from the second collection (in terms of reading the code). by similar logic, does the following read well enough to be acceptable?

(a.size< b.size)<-> (a.sizeIs< b)

does that read clearly/cleanly? can/does one's mind translate "a's size is less thanb" to "a's size is less thanb's size" automatically?

thoughts?

@NthPortal
Copy link
Contributor

since it hasn't been linked already, prior discussion happened atscala/collection-strawman#338 and#6950

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Labels
library:collectionsPRs involving changes to the standard collection librarylibrary:not-forward-bincompat
Projects
None yet
Milestone
2.13.17
Development

Successfully merging this pull request may close these issues.

5 participants
@wernerschram@SethTisue@NthPortal@lrytz@scala-jenkins

[8]ページ先頭

©2009-2025 Movatter.jp