最近Think ITがプログラミング言語の特集をやっている。 すばらしいことだと思う。
実は最初私に話が来たのだけど、 とても書けそうになかったので、ご遠慮したのだが、 ちゃんとライターを見つけてくるところがますますすばらしい。
で、今回はScalaなのだが、最後のここがちょっと不満。 いや、解説ではなくて言語に。
これらを踏まえてScalaが依然として静的型付け言語であるということを思い出してほしい。「動的言語の特徴のように見える物」が、実はそうでもないことがみえてくるのではないだろうか。実際Scalaを学んでいくと「型安全性と実行効率を引き換えに記述性と柔軟性を手に入れる」という「動的言語の常識」が覆されていくような感覚すら覚えるほどだ。
ここではDuckTyping(もどき)がScaleのstructural conformanceで 実現されているところをもって、上のように説明しているのだが、 実際にはRubyのプログラムとScalaのプログラムはこのようになっている。
Ruby版
def safe_close(x) x.close unless x.closed? end
Scala版
def safeClose(x)[T] (x: T {def isClosed: boolean; def close}) =
if (!x.isClosed) x.close;
うむ、確かにScala版でも、ある特定の型(IOとか)を指定しておらず、 isClosedとcloseがある任意のオブジェクトに対して呼び出せるので これはDuckTypingの「匂い」がする。
しかし、考えてみてほしい。この二つのプログラムには重大な違いがある。 それはScala版が簡潔ではないことだ。特にxの型指定の部分が。 safeCloseの例は簡単だが、 もっと複雑な関数なら引数それぞれがネストして structural conformanceな型を持つ可能性だってあるわけだし。 明示的な指定では、複雑になれば発狂しそうになるだろう。
この明示性はDuckTypingの思想とは対立する。
せっかく型推論があるのだから、指定などさせず、 「xに対してisClosedとcloseが呼ばれているから、xの型は〜」と きちんと推論してほしいものだ。実際にOCamlなどでは可能なのだから。
どこまで複雑なものまで可能かは知らないけど。
1.9のリリースに関連して、もう一度松江局でとりあげたいとのお話。
だが、それでなくてもこれから年内は予定がびっしり 詰まっているので、「年明けてからにしてください」とお願いした。
リリース前に取材したかったみたいで、 少々不満そうな気配も感じられたが、 勘弁してもらった。そろそろ限界が近い。
This work is licensed under a Creative Commons License.
明示的な指定が必要という点でDuck Typingと同じとは<br>言えないという点については確かにそうだと思います。<br>ただ、明示的な型指定では複雑になると発狂しそうになる<br>というのはちと言い過ぎかと。複雑な型については、Scala<br>では以下のようにして名前をつけることができるので、<br>十分実用的な範囲だと思います。<br><br>type SafeClosable = {<br> def isClosed :boolean<br> def close<br>}
書くのでは発狂しなくても、考えるのでしんどい気がします。<br>「なんとなくStringっぽい」とかいうイメージでは扱えないわけですから。<br>もっとも、「だから安心」という側面は否定できないので動的には良いことばかりではないですが。少なくともDuckTypingの「おおらかさ」(or「いいかげんさ」)とはだいぶ性質が異なる気がします。
「なんとなくStringっぽい」というイメージで扱うということ<br>についてもうちょっと詳しく説明していただくことはできる<br>でしょうか。<br><br>DuckTypingであろうとも、プログラムを書く/読むときには、<br>あるレシーバがどのようなメッセージの集合に応答可能<br>かというのを考えるはずですよね。で、Scalaではその<br>メッセージのシグニチャの集合についてそれを型として<br>明示するのだと考えれば、DuckTypingとの主要な違いは<br>記述量の多さかなと思ったのですが(method_missing<br>とかの話が入るとまた違うことになりそうですが、<br>とりあえずそれは置いておきます)。