scalayield-keyword

why yield can not work with while loop in scala


In Scala, yield can work with for-loops; for example:

val ints: IndexedSeq[Int] = for(i <- 1 to 10) yield i

But I found that yield can not work with while-loops, e.g. like:

while (resultSet.next()) yield new Row(resultSet)

Why is Scala designed like this?

I have searched on Google and stackoverflow, but could not find an answer.


Solution

  • Because a while loop is a java equivalent while loop, and the 'for loop' is translated to function call of: <IndexedSeq>.map (if you use yield) or <IndexedSeq>.foreach (if you don't care the result).

    Example Scala Code:

    class ForVsWhileLoop {
      val dummy = for(i <- 1 to 10) yield i
    
      var dummy2 = Seq.empty[Int]
      var i = 0
      while(i <= 10)
        dummy2 :+= i
    }
    

    Compiles to (scala -Xprint:parse ForVsWhileLoop.scala):

    [[syntax trees at end of                    parser]] // ForVsWhileLoop.scala
    package <empty> {
      class ForVsWhileLoop extends scala.AnyRef {
        def <init>() = {
          super.<init>();
          ()
        };
    
        // ***********************************************
        // the 'for loop' is translated to a function call
        val dummy = 1.to(10).map(((i) => i));
    
    
        var dummy2 = Seq.empty[Int];
        var i = 0;
    
        // *******************
        // classic while loop
        while$1(){
          if (i.$less$eq(10))
            {
              dummy2.$colon$plus$eq(i);
              while$1()
            }
          else
            ()
        }
      }
    }