-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Make Option extend IterableOnce #8038
Conversation
@szeiger pointed me to an older discussion: scala/collection-strawman#48
-- @szeiger
-- @Ichoran
-- @odersky
-- @sjrd |
Moving to RC2 just as a discussion item :) |
cd1ff6e
to
9dbc90f
Compare
I'd need some serious convincing on this another old discussion: scala/bug#7941 |
Note Option already implements a bunch of Iterable methods in 2.13.x and 2.12.x because there's an implicit conversion to Iterable. So I find it odd that we don't allow the following to be interchangeable: scala> for { i <- List(1, 2); j <- Some("a") } yield (i, j)
res2: List[(Int, String)] = List((1,a), (2,a))
scala> for { j <- Some("a"); i <- List(1, 2) } yield (i, j)
<console>:12: error: type mismatch;
found : List[(Int, String)]
required: Option[?]
for { j <- Some("a"); i <- List(1, 2) } yield (i, j)
^ |
I am honestly not in favour - |
I am not sure what intuition we can use to test if something is a collection or not. To me, personally If Scala goes the direction of we don't mix-and-match things in |
With that argument, |
Could there be some negative consequences for the FP folks / cats? In any case, given that it's not a clear yes, I don't think we should rush it for 2.13. |
I missed it originally, so in case anyone else missed it: def iterator: Iterator[A]
def stepper[B >: A, S <: Stepper[_]](implicit shape: StepperShape[B, S]): S
def knownSize: Int That, in itself, makes it a more palatable. But there is also @`inline` implicit def iterableOnceExtensionMethods[A](it: IterableOnce[A]): IterableOnceExtensionMethods[A] which brings all the old methods back, albeit deprecated. So, on balance, I'm still unconvinced. |
It is true that you get a lot of (potentially unwanted) collection operations via I am generally in favor of making this change but there is still the caveat about unboxed options in Dotty (which may not be possible if |
discussed at team meeting just now there were two threads of discussion:
I'm a strong "no" on the first, a weaker "no" on the second (if we agree it's too late for 2.13, we have time to think on the second question. Dale and Lukas have pointed out that |
Maybe it is fine to make Option implement IterableOnce, after all. I'm a bit worried by strongly coupling Option with the collections, but I can not really find a strong argument against this. And as other have mentioned, there is already a coupling because of the conversion to Iterable. If we discover that making Option implement IterableOnce is not a good idea, we can probably easily remove that inheritance relationship in 2.14 and still be source compatible with existing code bases because of the conversion to Iterable. |
About IerableOnceExtensionMethods: are we sure that operations currently provided by the conversion to Iterable won't become deprecated if Option extends IterableOnce? |
That part seems fine: scala> Option(1).min
res7: Int = 1
scala> (Option(1): IterableOnce[Int]).min
^
warning: method min in class IterableOnceExtensionMethods is deprecated (since 2.13.0): Use .iterator.min instead
res8: Int = 1 |
Discussing with @odersky, he felt the regression of having to ascribe an explicit type to the result of the function is worse than the risk (if any) of having I'm tentatively rescheduling for RC2 based on this, but let's have one more round of discussion before we merge. |
To streamline the discussions, let's discuss two points:
I lean towards "yes" on both counts. I think this is important enough to fix now, rather than in 2.14. |
The added methods are:
|
Is there really no other fix for the original issue? Like adding an overload of |
Yes, adding overloads would also work, see scala/bug#11033 (comment). We'd have to also do it for other collections that intorduce a flatMap overload, like BitSet, IntAccumulator. |
I'm not convinced (yet?) adding overloads for |
You'd cache these instances up to some level (and have special code paths for level 0 and possibly level 1 for further optimization). The erasure of |
making decisions on a datatype "Truely belonging somewhere" based on the
english meaning of the name of a trait that the data type should or
shouldn't inherit from seems to me a dangerous guide for this decision.
…On Thu, May 9, 2019 at 2:31 PM Josh ***@***.***> wrote:
I do think it is kind of awkward that Option would extend IterableOnce and
not Iterable, if it were to extend any, Seeing as it is, in fact
iterableMoreThanOnce and therefor truly belongs in the Iterable family
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#8038 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAGXOEOXULGOLK73SFANS7LPUQKTXANCNFSM4HLACK6Q>
.
|
When starting on a blank slate, I would rename |
Sorry, I didn't mean that the English name sounds better one way or the other, but that the definition / semantics of Iterable are more suitable to Option than IterableOnce is, because the difference between Iterable and IterableOnce is that Iterable can be iterated multiple times while an IterableOnce cannot (necessarily). Option can be iterated many times, so it belongs in Iterable. |
Let's add to the docs to help with people's mental model. |
The 2.12 Scaladoc for Option says, and have said for years, on line 2:
Most books and training material build on this. The fallout from changing this message, and hence people's mental model, would be considerable. |
Ah, I didn't consider that variant! I pushed that change for once, to make the discussion more concrete. |
Thinking about it, the downside of the fuller change (to extend So overall, extending |
e6dbd26
to
294f098
Compare
Here is a variant that does that: sjrd/scala-unboxed-option#4
That's literally what |
294f098
to
a002aca
Compare
In 2.13.0-RC2, it's not nice getting deprecation messages for |
To be clear, the deprecation is about |
So, yeah, now I can't remember why we didn't mix |
Perhaps because it contains a number of methods that don't make sense for |
|
discussion on this at https://gitter.im/scala/contributors?at=5ce4f1ab13e9854e3346eb2c (started by @Sciss) (UPDATE: archived at scala/scala-lang#1317 (comment)) this seems especially annoying:
the workaround is |
#8106 un-deprecates |
- Clarify whether Option is considered a collection - Explain implicit conversion option2iterable - Address comment scala/scala#8038 (comment) documenting metal model of Iterable -> Collection and IterableOnce -> Iterable
scala/bug#11033
Option cannot be
Iterable
because we'd have to implement