For expressions versus foreach in Scala

I am making my way through Scala Programming , and although I am tempted to look at things from a Python perspective, I don't want to program "Python in Scala."

I'm not quite sure what to do with the control flow: in Python we use for x in some_iterable to die, and we like it. A very similar construct exists in Scala, which Odersky calls a for statement, probably to distinguish it from the Java for loop. In addition, Scala has a foreach attribute (I think it would be an attribute, I don’t know enough about Scala to call it correctly) for duplicate data types. I can't seem to use foreach to do much more than calling one function for each element in the container.

This leaves me with a few questions. Firstly, for expressions, important / heavily used constructions in Scala, like in Python, and secondly, when should you use foreach instead of a for expression (except for the obvious case of calling a function for each element of a container)?

I hope I'm not terribly ambiguous or too shy, but I'm just trying to understand some of the basics of design / language in Scala (which seems very cool so far).

+53
loops scala foreach
Dec 16 '10 at 23:27
source share
5 answers

python uses for in list expressions and generator expressions. They are very similar to the scala for expression:

this is python

 >>> letters = ['a', 'b', 'c', 'd'] >>> ints = [0, 1, 2, 3] >>> [l + str(i) for l in letters for i in ints if i % 2 == 0] ['a0', 'a2', 'b0', 'b2', 'c0', 'c2', 'd0', 'd2'] 

this is scala

 scala> val letters = List('a', 'b', 'c', 'd') scala> val ints = List(0, 1, 2, 3) scala> for (l <- letters; i <- ints if i % 2 == 0) yield l.toString + i res0: List[java.lang.String] = List(a0, a2, b0, b2, c0, c2, d0, d2) 

Each construct can take several generators / iterators, apply filter expressions and give a combined expression. In python (expr for v1 in gen1 if expr1 for v2 in gen2 if expr2) roughly equivalent:

 for v1 in gen1: if expr1: for v2 in gen2: if expr2: yield expr 

In scala for (v1 <- gen1 if expr1; v2 <- gen2 if expr2) yield expr roughly equivalent:

 gen1.withFilter(expr1).flatMap(v1 => gen2.withFilter(expr2).map(v2 => expr)) 

If you like the python for x in xs syntax, you will most likely like the scala for expression.

Scala has some additional syntax and translation twists. The wise for syntax can be used with curly braces so you can put statements on separate lines. You can also perform value assignments.

 val res = for { i <- 1 to 20; i2 = i*i j <- 1 to 20; j2 = j*j k <- 1 to 20; k2 = k*k if i2 + j2 == k2 } yield (i, j, k) 

Also v1 <- gen1 does indeed match case v1 => gen1 . If there is no match, these elements are ignored in the iteration.

 scala> val list = List(Some(1), None, Some(2)) scala> for (Some(i) <- list) yield i res2: List[Int] = List(1, 2) 

I think that for occupies an important place in this language. I can tell from the fact that in this book you read the whole chapter (23)!

+58
Dec 17 '10 at 4:02
source share

Yes, Scala uses a lot to understand (as they are widely known), but they are really just syntactic sugar for a certain combination of methods, and many prefer to call these methods directly, instead of using syntactic sugar.

To better understand Scala for understanding, see this question . In particular, you will see that for (x <- xs) f(x) is the same as xs.foreach(x => f(x)) .

Now you will note that you are not using the foreach method very well, but I will point out that almost all Scala collection methods (or can be implemented) are implemented using foreach only. See the documentation for Traversable - all its methods can only be implemented using foreach .

Note that Scala yield has no resemblance to Python yield - you can look for this question .

+24
Dec 17 2018-10-12T00:
source share

Thanks to the support of nested iterations, filters and transformations, I would say that Scala for is one of the strengths of the language and very central. I prefer to use it with foreach , map and filter .

+3
Dec 16 '10 at 23:40
source share

Preview is a functional style, while for is an imperative style. If you have ever done any lisp or schema, you are already familiar with functional programming. If you haven’t done this, then at first it can be a bit confusing. The first thing I would like to do is read the closure syntax, which is anonymous functions that you pass in things like foreach. As soon as you understand that all this will make sense.

+3
Dec 16 '10 at
source share

Your questions are mainly answered:

Scala For Understanding

Scala Profitability

To summarize: this is pretty much stylistic. Personally, I advocate a functional methodology, but I prefer laconic understanding when working with nested loops.

+3
Dec 17 2018-10-12T00:
source share