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).
-
PostfixPostfixif
goes away. Use destructuring for conditionals instead.if
and incomplete destructuring both go away. Usecase
instead (withif
as needed, as inmatch
). -
yield
has a type parameter that you can use to specify the element type. -
foreach
version 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