世間的にも。アリエル的にも今更ですが。Scala がメチャおもろいです。どのくらいかと言うと。普段控えめな自分が Java を上から目線でディスりたくなるくらいおもろいです。
というわけで。Scala の話をします。ネタは Stream です。
リストの要素を遅延評価してくれる Stream は、Lisp 脳のプログラマにとっては、とってもおもろいデータ構造です。
例えば。List だと即座にメモリを取りにいくので、↓ こういうようなことはそうそう出来ません。
1 2 3 |
scala> val hoge = 0 to 1000000000 toList java.lang.OutOfMemoryError: Java heap space ... |
が。Stream だと、実際に参照されるまで評価されないので、上述の処理も一瞬でできます。
1 2 |
scala> val hoge = 0 to 1000000000 toStream hoge: scala.collection.immutable.Stream[Int] = Stream(0, ?) |
他のこいつを使ったオモロい実例は、他の人がいろいろ書いてくれているのでそっちを参照してください。
http://blog.livedoor.jp/sylc/archives/1557536.html
http://d.hatena.ne.jp/yuroyoro/20110418/1303110333
さて、ここからが本題。
Stream は参照されるまで評価されないので。まだ参照されてないけど、巨大になる(または無限になる)ことが予想されるリストを扱う際には、とっても重宝します。そういったリストを転送する場合なんかは特に。
例えば、他のプロセス(もしくは他のマシンのプロセス)にリストを送る場合を考えてみましょう。
送信元のプロセスでメモリに載ってるリストが、他のプロセスや他のマシンのプロセスのメモリに載っかるとは限りません。
そんな時は Stream にすれば、メモリを一気にバカ食いしたり、メモリに乗り切らないでエラーを吐くといった事にはならなそうです。
ただここで問題が。。。
— Stream.Empty オブジェクトが Serializable じゃない orz…
(http://www.scala-lang.org/api/current/scala/collection/immutable/Stream$$Empty$.html)
なのでリモートアクターを使って、以下のように Stream を直に転送するなんて事ができません。
1 2 3 |
... val server = select(Node(host, port), 'TestServer) server ! Stream.cons(1, Stream.cons(2, Stream.empty)) |
ではどうするか?
アリエルや他の Scala ハッカーにどうしてるか聞きたいところですが。何もしないで「教えてくれ」と言うと、(先日の CTO からの厳しい発言があった折から)社内的にも社会的にも淘汰される可能性があるので。以下、『つくってみた』の話。
[(長くなりそうなので)次回 に続く]
最近のコメント