Onionには以前自動ダウンキャストという今となっては黒歴史にしたい機能が入っていたことがあった*1。どういう機能かというと、たとえば、Object型の変数oをダウンキャストしてString型の変数sに入れたいとする。Javaだと以下のような感じだ。
Object o = ...;
String s = (String)o;
以前のOnionでは、このような場合、以下のように書くことで、処理系が自動的にダウンキャストを挿入してくれていた。
o: Object = ...; s : String = o; //明示的なキャストを省ける!
ジェネリクスが無いOnionで少しでも利便性を上げようとして導入した機能だったが*2、変数の代入時に発動するだけならともかく、メソッド呼び出し時の引数渡しでも発動するようにしようと考えると、関数のオーバーローディング規則が無意味に複雑化する&直感的でない動作になる事に気づいて、結局Onionからは削除したという経緯がある。だが、先ほどFantom Programming Languageのドキュメントを改めて眺めていたら、どうもFantomにその機能があるらしい事に気づいた。FantomではImplicits Castと呼んでいるらしいが、やっていることはほとんど同じである。以下、Fantomのドキュメントから引用する:
For example:
Int func(Int x) { ... } Int i := 5 Num n := 5 Str s := "foo" // statically correct as is: Int.fits(Int) func(i) => func(i) // implicit cast inserted: Int.fits(Num) func(n) => func((Int)n) // compile time error: !Int.fits(Str) func(s) => errorhttp://fantom.org/doc/docLang/TypeSystem.html
Onionではオーバーロード規則がやたら複雑化するために、メソッド呼び出し時の引数渡しに伴う自動キャストまでは実装しなかったのだが、Fantomではそれも実装されてしまっている!Fantomではメソッドオーバーローディングが存在しないため、これを実装してしまっても問題無いということなんだろうか。この言語の作者に妙に親近感を覚えてしまった。まあ、Fantomの方がずっとちゃんと処理系が作られているし、Onionなんかと比較するのは失礼かもしれんけど。
*1:SourceForge.jpからリリースされているビルドの最新版には今も入っているが、リポジトリの最新版では削除されている
*2:確か、G言語(まともなドキュメントが残ってないが、現在は[http://en.wikipedia.org/wiki/Deesel:title=Deesel]?)の仕様を見て取り入れたんだったと記憶している