Fight the Future

Java言語とJVM、そしてJavaエコシステム全般にまつわること

Scalaのfor文はシンタックスシュガー

次のExampleはforのことみたいだったけど、コードが長いので少し自分で調べてみた。

forループは文法ではなく,for-comprehensionという一種のシンタックスシュガーして定義され,map, filter等に変換される。

第3回 Scala言語を探検する(1):ITpro

ということなので、試してみる。

package sample.snippet

object ForSample extends Application {  
  for (val i <- 1 to 10)
    println(i)
}

で、このコードに対してscalac -Xprint:nameを使えば、デシュガーできるらしい。

"scalac -Xprint:namer" will show the result of desugar for the syntax sugar.

[http://wassr.jp/channel/scala/messages/tzN9QJqGUQ:title=[scala] "scalac -Xprint:namer" will show the result of desugar for the syntax sugar. - Wassr [お気軽メッセージングハブ・ワッサー]]

デシュガーする。

$ scalac -Xprint:namer sample/snippet/ForSample.scala
[[syntax trees at end of namer]]// Scala source: ForSample.scala
package sample {
  package snippet {
    final object ForSample extends Application with scala.ScalaObject {
      def <init>() = {
        super.<init>();
        ()
      };
      1.to(10).foreach(((i) => println(i)))
    }
  }
}

なるほど。実際はforeachに無名関数を渡す形になってる。


少しコードを変えてみよう。

package sample.snippet

object ForSample extends Application {  
  for (val i <- 1 to 10 if i % 2 != 0)
    println(i)
}

forに条件をつけて奇数だけ出力するようにしてみた。
これもデシュガーする。

$ scalac -Xprint:namer sample/snippet/ForSample.scala
[[syntax trees at end of namer]]// Scala source: ForSample.scala
package sample {
  package snippet {
    final object ForSample extends Application with scala.ScalaObject {
      def <init>() = {
        super.<init>();
        ()
      };
      1.to(10).filter(((i) => i.$percent(2).$bang$eq(0))).foreach(((i) => println(i)))
    }
  }
}

おお!今度はfilterの実装になった。