なんか、よく解らないくなったので書き捨て気味。
Scalaのfor文に謎の制限があった気がしたので調査してみた。
for{ x<-List(1) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) x<-List(x) }yield x
こんな感じのコードを書いてみると、エラーになったはず。
res0: List[Int] = List(1)
あれ?余裕だった。こんなはずじゃ・・・
for{ x<-List(1) x<-List(2) x<-List(3) x<-List(4) /*...省略...*/ x<-List(80) }yield x That entry seems to have slain the compiler. Shall I replay your session? I can re-run each line except the last one. [y/n] Abandoning crashed session.
お。何やらエラーが出た。
REPLだと、エラーがスクロールアウトしてしまうので、コンパイルしてみる。
object ForTest { def main(args: Array[String]): Unit = { val res = for{ x<-List(1) x<-List(2) x<-List(3) x<-List(4) /*...省略...*/ x<-List(80) }yield x print(res) } }
エラーメッセージをリダイレクトしてみてみると。
error: java.lang.StackOverflowError at scala.tools.nsc.symtab.Symbols$Symbol.ownerChain(Symbols.scala:611) at scala.tools.nsc.symtab.Symbols$Symbol.ownerChain(Symbols.scala:611) at scala.tools.nsc.symtab.Symbols$Symbol.ownerChain(Symbols.scala:611) ...省略...
何やらスタックオーバーフローのようだ。
限界を探る。とりあえず、50段でどうだ。
object ForTest { def main(args: Array[String]): Unit = { val res = for{ x<-List(1) x<-List(2) x<-List(3) x<-List(4) /*...省略...*/ x<-List(50) }yield x print(res) } }
( ゜Д ゜)
なんか、フォルダがすごいことになってる。
for.scala ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$2ba3c985645ec38325c378bf7e92d5f4$$$$apply$37$$anonfun$apply$38$$anonfun$apply$39$$anonfun$apply$40$$anonfun$apply$41$$anonfun$apply$42$$anonfun$apply$43$$anonfun$apply$44.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$2ba3c985645ec38325c378bf7e92d5f4$$$$apply$37$$anonfun$apply$38$$anonfun$apply$39$$anonfun$apply$40$$anonfun$apply$41$$anonfun$apply$42$$anonfun$apply$43.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$2ba3c985645ec38325c378bf7e92d5f4$$$$apply$37$$anonfun$apply$38$$anonfun$apply$39$$anonfun$apply$40$$anonfun$apply$41$$anonfun$apply$42.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$2ba3c985645ec38325c378bf7e92d5f4$$$$apply$37$$anonfun$apply$38$$anonfun$apply$39$$anonfun$apply$40$$anonfun$apply$41.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$2ba3c985645ec38325c378bf7e92d5f4$$$$apply$37$$anonfun$apply$38$$anonfun$apply$39$$anonfun$apply$40.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$3f4b974217354c913b39e68ff8b2b6bc$$$$$apply$47$$anonfun$apply$48$$anonfun$apply$49$$anonfun$apply$1.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$91e13cecb8c4b0155330a013f9c28a9a$$$$apply$22$$anonfun$apply$23$$anonfun$apply$24$$anonfun$apply$25$$anonfun$apply$26$$anonfun$apply$27$$anonfun$apply$28$$anonfun$apply$29.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$91e13cecb8c4b0155330a013f9c28a9a$$$$apply$22$$anonfun$apply$23$$anonfun$apply$24$$anonfun$apply$25$$anonfun$apply$26$$anonfun$apply$27$$anonfun$apply$28.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$91e13cecb8c4b0155330a013f9c28a9a$$$$apply$22$$anonfun$apply$23$$anonfun$apply$24$$anonfun$apply$25$$anonfun$apply$26$$anonfun$apply$27.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$91e13cecb8c4b0155330a013f9c28a9a$$$$apply$22$$anonfun$apply$23$$anonfun$apply$24$$anonfun$apply$25$$anonfun$apply$26.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$91e13cecb8c4b0155330a013f9c28a9a$$$$apply$22$$anonfun$apply$23$$anonfun$apply$24$$anonfun$apply$25.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$9995e2ab6ae69e214fd9c05d51f994af$$$$apply$32$$anonfun$apply$33$$anonfun$apply$34$$anonfun$apply$35$$anonfun$apply$36$$anonfun$apply$37$$anonfun$apply$38$$anonfun$apply$39.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$9995e2ab6ae69e214fd9c05d51f994af$$$$apply$32$$anonfun$apply$33$$anonfun$apply$34$$anonfun$apply$35$$anonfun$apply$36$$anonfun$apply$37$$anonfun$apply$38.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$9995e2ab6ae69e214fd9c05d51f994af$$$$apply$32$$anonfun$apply$33$$anonfun$apply$34$$anonfun$apply$35$$anonfun$apply$36$$anonfun$apply$37.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$9995e2ab6ae69e214fd9c05d51f994af$$$$apply$32$$anonfun$apply$33$$anonfun$apply$34$$anonfun$apply$35$$anonfun$apply$36.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$9995e2ab6ae69e214fd9c05d51f994af$$$$apply$32$$anonfun$apply$33$$anonfun$apply$34$$anonfun$apply$35.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$c6bb6e876993f62e2f410c3d58526$$$$apply$27$$anonfun$apply$28$$anonfun$apply$29$$anonfun$apply$30$$anonfun$apply$31$$anonfun$apply$32$$anonfun$apply$33$$anonfun$apply$34.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$c6bb6e876993f62e2f410c3d58526$$$$apply$27$$anonfun$apply$28$$anonfun$apply$29$$anonfun$apply$30$$anonfun$apply$31$$anonfun$apply$32$$anonfun$apply$33.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$c6bb6e876993f62e2f410c3d58526$$$$apply$27$$anonfun$apply$28$$anonfun$apply$29$$anonfun$apply$30$$anonfun$apply$31$$anonfun$apply$32.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$c6bb6e876993f62e2f410c3d58526$$$$apply$27$$anonfun$apply$28$$anonfun$apply$29$$anonfun$apply$30$$anonfun$apply$31.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$c6bb6e876993f62e2f410c3d58526$$$$apply$27$$anonfun$apply$28$$anonfun$apply$29$$anonfun$apply$30.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$e53f4f99c30ac7a10a09f551d71578c$$$$apply$12$$anonfun$apply$13$$anonfun$apply$14$$anonfun$apply$15$$anonfun$apply$16$$anonfun$apply$17$$anonfun$apply$18$$anonfun$apply$19.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$e53f4f99c30ac7a10a09f551d71578c$$$$apply$12$$anonfun$apply$13$$anonfun$apply$14$$anonfun$apply$15$$anonfun$apply$16$$anonfun$apply$17$$anonfun$apply$18.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$e53f4f99c30ac7a10a09f551d71578c$$$$apply$12$$anonfun$apply$13$$anonfun$apply$14$$anonfun$apply$15$$anonfun$apply$16$$anonfun$apply$17.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$e53f4f99c30ac7a10a09f551d71578c$$$$apply$12$$anonfun$apply$13$$anonfun$apply$14$$anonfun$apply$15$$anonfun$apply$16.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$e53f4f99c30ac7a10a09f551d71578c$$$$apply$12$$anonfun$apply$13$$anonfun$apply$14$$anonfun$apply$15.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$f0755ad498a7139e63eab85543dc6e$$$$apply$17$$anonfun$apply$18$$anonfun$apply$19$$anonfun$apply$20$$anonfun$apply$21$$anonfun$apply$22$$anonfun$apply$23$$anonfun$apply$24.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$f0755ad498a7139e63eab85543dc6e$$$$apply$17$$anonfun$apply$18$$anonfun$apply$19$$anonfun$apply$20$$anonfun$apply$21$$anonfun$apply$22$$anonfun$apply$23.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$f0755ad498a7139e63eab85543dc6e$$$$apply$17$$anonfun$apply$18$$anonfun$apply$19$$anonfun$apply$20$$anonfun$apply$21$$anonfun$apply$22.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$f0755ad498a7139e63eab85543dc6e$$$$apply$17$$anonfun$apply$18$$anonfun$apply$19$$anonfun$apply$20$$anonfun$apply$21.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$f0755ad498a7139e63eab85543dc6e$$$$apply$17$$anonfun$apply$18$$anonfun$apply$19$$anonfun$apply$20.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$fbc7d1b81196c14bfe749fcb407d9887$$$$apply$42$$anonfun$apply$43$$anonfun$apply$44$$anonfun$apply$45$$anonfun$apply$46$$anonfun$apply$47$$anonfun$apply$48$$anonfun$apply$49.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$fbc7d1b81196c14bfe749fcb407d9887$$$$apply$42$$anonfun$apply$43$$anonfun$apply$44$$anonfun$apply$45$$anonfun$apply$46$$anonfun$apply$47$$anonfun$apply$48.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$fbc7d1b81196c14bfe749fcb407d9887$$$$apply$42$$anonfun$apply$43$$anonfun$apply$44$$anonfun$apply$45$$anonfun$apply$46$$anonfun$apply$47.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$fbc7d1b81196c14bfe749fcb407d9887$$$$apply$42$$anonfun$apply$43$$anonfun$apply$44$$anonfun$apply$45$$anonfun$apply$46.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$$$$$fbc7d1b81196c14bfe749fcb407d9887$$$$apply$42$$anonfun$apply$43$$anonfun$apply$44$$anonfun$apply$45.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6$$anonfun$apply$7$$anonfun$apply$8$$anonfun$apply$9$$anonfun$apply$10$$anonfun$apply$11$$anonfun$apply$12$$anonfun$apply$13$$anonfun$apply$14.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6$$anonfun$apply$7$$anonfun$apply$8$$anonfun$apply$9$$anonfun$apply$10$$anonfun$apply$11$$anonfun$apply$12$$anonfun$apply$13.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6$$anonfun$apply$7$$anonfun$apply$8$$anonfun$apply$9$$anonfun$apply$10$$anonfun$apply$11$$anonfun$apply$12.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6$$anonfun$apply$7$$anonfun$apply$8$$anonfun$apply$9$$anonfun$apply$10$$anonfun$apply$11.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6$$anonfun$apply$7$$anonfun$apply$8$$anonfun$apply$9$$anonfun$apply$10.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6$$anonfun$apply$7$$anonfun$apply$8$$anonfun$apply$9.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6$$anonfun$apply$7$$anonfun$apply$8.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6$$anonfun$apply$7.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$apply$4$$anonfun$apply$5.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$apply$4.class ForTest$$anonfun$1$$anonfun$apply$2$$anonfun$apply$3.class ForTest$$anonfun$1$$anonfun$apply$2.class ForTest$$anonfun$1.class ForTest$.class ForTest.class
何が起きてる!?!?!?
ので、とりあえず最少構成っぽいコードを書く。
object ForTest { def main(args: Array[String]): Unit = { val list_x = List(1,2,3) val list_y = List(4,5,6) val res = for{ x<-list_x y<-list_y }yield x + y print(res) } }
コンパイルしてみる。
なんか、少しだけファイルができる。
ForTest$$anonfun$1$$anonfun$apply$1.class ForTest$$anonfun$1.class ForTest$.class ForTest.class
逆コンパイル。
ForTest.class
import scala.reflect.ScalaSignature; @ScalaSignature(bytes="\006\0015:Q!\001\002\t\006\025\tqAR8s)\026\034HOC\001\004\003\035aT-\0349usz\032\001\001\005\002\007\0175\t!AB\003\t\005!\025\021BA\004G_J$Vm\035;\024\007\035Q!\003\005\002\f!5\tAB\003\002\016\035\005!A.\0318h\025\005y\021\001\0026bm\006L!!\005\007\003\r=\023'.Z2u!\t\031b#D\001\025\025\005)\022!B:dC2\f\027BA\f\025\005-\0316-\0317b\037\nTWm\031;\t\013e9A\021\001\016\002\rqJg.\033;?)\005)\001\"\002\017\b\t\003i\022\001B7bS:$\"AH\021\021\005My\022B\001\021\025\005\021)f.\033;\t\013\tZ\002\031A\022\002\t\005\024xm\035\t\004'\0212\023BA\023\025\005\025\t%O]1z!\t9#F\004\002\024Q%\021\021\006F\001\007!J,G-\0324\n\005-b#AB*ue&twM\003\002*)\001") public final class ForTest { public static final void main(String[] paramArrayOfString) { ForTest..MODULE$.main(paramArrayOfString); } }
ForTest$.class
import scala.Predef.; import scala.ScalaObject; import scala.collection.TraversableLike; import scala.collection.immutable.List; import scala.collection.immutable.List.; public final class ForTest$ implements ScalaObject { public static final MODULE$; static { new (); } public void main(String[] args) { List list_x = List..MODULE$.apply(Predef..MODULE$.wrapIntArray(new int[] { 1, 2, 3 })); List list_y$1 = List..MODULE$.apply(Predef..MODULE$.wrapIntArray(new int[] { 4, 5, 6 })); List res = (List)list_x.flatMap(new ForTest..anonfun.1(list_y$1), List..MODULE$.canBuildFrom()); Predef..MODULE$.print(res); } private ForTest$() { MODULE$ = this; } }
ForTest$$anonfun$1.class
import scala.Serializable; import scala.runtime.AbstractFunction1.mcII.sp; public final class ForTest$$anonfun$1$$anonfun$apply$1 extends AbstractFunction1.mcII.sp implements Serializable { public static final long serialVersionUID = 0L; private final int x$1; public final int apply(int y) { return apply$mcII$sp(y); } public int apply$mcII$sp(int v1) { return this.x$1 + v1; } }
ForTest$$anonfun$1$$anonfun$apply$1.class
class
{
}
とりあえず、うわさ通りflatMapに展開されているということは、解った。あと、yield処理は、apply$mcII$sp()に展開されている。
Scalaのコンパイラが、forのシンタックスシュガーを自動的に内部クラスに展開するらしいことは、解った。そんで、ネストが深くなると、クラスの定義がドエライことになってコンパイラがスタックオーバーフローすることも解ったような気がする。
この感じだと、forが何重までネストできるかは、環境依存っぽいな。あと、23〜24段でエラーになっていた気がしたのは、32bitのWindows XP環境だったからかな?
今回のコードを2.8.0.final, 2.8.2.final, 2.9.0.final, 2.9.1.finalで試してみたけど、どれも同じ挙動だった。