I don’t normally hear people complaining about for (maybe because it’s awesome), but it has a huge number of irregularities compared to “normal” Scala, and despite having used it for about a decade now, I don’t always immediately recall every detail of how to use it effectively.
Since Scala is getting a bit of a facelift with Dotty anyway, now seems like an ideal time to consider how to freshen up for to be a little less weird.
Which aspects of the behavior of for, if any, do you find particularly incongruous or difficult to get working?
For me, the top two are for() vs for{}, and the sudden ability to assign to create vals through simple assignment. But there are a bunch of things.
I have a mock proposal for a more uniform for as a potential starting point for discussion.
-
for()allows only a single statement. Usefor{}for multiple statements. - Assignment uses normal syntax; both vals and vars are fine, and are desugared exactly as you would expect (i.e. placed in the body of the method).
-
PostfixPostfixifgoes away. Use destructuring for conditionals instead.ifand incomplete destructuring both go away. Usecaseinstead (withifas needed, as inmatch). -
yieldhas a type parameter that you can use to specify the element type. -
foreachversion goes away.
I’m pretty sure this is not complete enough, but it is much simpler to understand than the existing for. Edit: missed “not” before! Very important not!
Examples:
for (a <- List(1, 2)) yield 3*a
for {
a <- List(1, 2)
val b = 3*a
} yield a*b
// Gives a compiler error instead of Vector((), (), (), ())
for (c <- "fish") yield[Char] (if (c < 'c') c)
New suggestion of using case:
for {
case Left((x, "salmon")) <- myEither
} yield x + x