アノテーションを使った型の表現

「関数定義に java のアノテーションのような記法を使うことで, 引数の条件を記述できるんじゃないか?」というアイディアを発端とした, @PG_kura さんと @cocoatomo の一連の会話. 正直, まだ頭の中がまとまってないので, 曖昧な部分の多い会話になりました.
2
tomo🐧@learning @cocoatomo

数学の式の表記とソースコードって似てるけど、何故かソースコードの方が見づらい。 んで、さっきふと気付いたのは、数学の場合「この表記だったら、この変数はこういうもののはず」というような表記の定義から、変数の暗黙の前提条件を逆算している。(続く)

2010-08-11 10:57:59
tomo🐧@learning @cocoatomo

(続き) そうなると、今ある型だけでは不足している。range 型や even 型のような今ある型をさらに狭めた型が必要。コンパイルや実行時にそれを自動でチェックしてくれる機構も必要。 組み合わせが複雑になることに備えて、 #java のアノテーションのようなものが良いと思う。

2010-08-11 10:57:30
tomo🐧@learning @cocoatomo

(続き) 引数として入ってくる値にいくつかパターンがある場合は、パターンマッチングが最適かな?

2010-08-11 10:57:46
tomo🐧@learning @cocoatomo

@PG_kura この Tweet の Reply 先を間違えていた気がする...

2010-08-12 00:07:40
tomo🐧@learning @cocoatomo

@PG_kura 「多重ディスパッチ」って何に対しての発言だったのでしょうか??

2010-08-12 00:14:39
くっくっkura 🇯🇵🦀 @PG_kura

@cocoatomo これ(http://twitter.com/cocoatomo/status/20845634557)ですね。内容を把握できてなかったのですが、組み合わせとか書いてたのでとりあえず多重ディスパッチとどう違うのかなーというのを聞いてみたかったのです。

2010-08-12 00:17:13
tomo🐧@learning @cocoatomo

@PG_kura 多重ディスパッチって「オーバーロードの解決を動的に行うようなもの」という理解でいいんですかね? 想定していたのは, 1つの引数に対して複数のアノテーションを付ける場面です. range と even (← 偶数) というアノテーションは独立で (続く)

2010-08-12 00:25:50
tomo🐧@learning @cocoatomo

@PG_kura def method(int a @even @range(2, 20))... みたいに付けておくと, 呼び出したときに勝手に「偶数チェック」と「範囲チェック」をやるようなイメージでした. こういう定型的なチェックはいちいちロジック書かずに済ませたいッス.

2010-08-12 00:29:54
くっくっkura 🇯🇵🦀 @PG_kura

@cocoatomo あー、なるほど。そういうことですか。しかしそれは型 int を even で 2 ~ 20 の値に限定するような MyInt にする、ということとは違うのでしょうか?

2010-08-12 00:35:10
tomo🐧@learning @cocoatomo

@PG_kura 本質的には違いません. ただ, @even, @range, @nonzero, @positive などと増えていった場合に, それらの組み合せに対してクラスを作っていったら管理が面倒になります. 名前もきっと EvenNonzeroInt みたいになるだろし

2010-08-12 00:40:28
くっくっkura 🇯🇵🦀 @PG_kura

@cocoatomo ですね。名前をつけていくとそうなりますよね。Scala に trait ってのがありまして、こいつは、まぁ実装を兼ねたインターフェイスなのですが、インラインでクラスを練成したりできるのですよ。で、しかも型推論があるので型安全。(続く)

2010-08-12 00:42:35
tomo🐧@learning @cocoatomo

@PG_kura #java の子クラス爆発が嫌いなので, できればアドオンの形で型を増やしたいです. これは個人的な感情ですが. このアイディアが筋が良いかは実際にソース書いてみないと分からないです. 早よ書きます.

2010-08-12 00:44:04
くっくっkura 🇯🇵🦀 @PG_kura

@cocoatomo プレーンな class MyInt が定義されていて、 trait Even extends MyInt とかを別で定義してあげるわけです。で、 val i = new MyInt with Even; とかやってやるとそのばで無名クラスのインスタンスが。

2010-08-12 00:44:59
くっくっkura 🇯🇵🦀 @PG_kura

@cocoatomo 型の爆発を防ぐということや型安全であるということも含め、恐らく Scala の trait は @cocoatomo さんが欲している要素の多くを満たしていると思います。参考になればと思います。

2010-08-12 00:46:52
tomo🐧@learning @cocoatomo

@PG_kura メソッドの先頭での null チェックや範囲チェックなどを簡単に書きたいなー, という動機でアノテーションを欲してました. メソッドを定義するたびに型を作ったりするのは重いと思うので. そっちの方でも trait は使えますかね?

2010-08-12 00:52:37
くっくっkura 🇯🇵🦀 @PG_kura

@cocoatomo まず null チェックはそもそも null リテラルを使わずに Option を使うのでそれは trait なしで解決されます。で、実際のコードで関数の引数として妥当な型を練成できるか、というと、それは微妙ですねー。無いより良いですが最適解ではないです。

2010-08-12 00:55:47
くっくっkura 🇯🇵🦀 @PG_kura

@cocoatomo even や range のような汎用的なものであれば使い回しが効くので良いですが、たぶんアプリケーションのその関数だけに特化したような属性、というのも出てくると思うのでそういうところまで手が届くか、というとう~ん、といった感じです。

2010-08-12 00:57:34
tomo🐧@learning @cocoatomo

@PG_kura 特殊なのが必要な場合はアノテーションを自作してしまえば良いかなぁ, と思ってます. #python のデコレータを使えばなんとかなるだろ, と思ってます.

2010-08-12 01:04:04
tomo🐧@learning @cocoatomo

@PG_kura なんでこんな考えに至ったかと言うと, Knuth 先生の WEB や javadoc を知り, さらに JUnit4 みたいなアノテーションばりばりのフレームワークを知ったことで, ソースコードでは表せないメタな情報もコンパイルしたい!! という欲求が出たんです

2010-08-12 01:05:57
くっくっkura 🇯🇵🦀 @PG_kura

@cocoatomo python は詳しくないですがアノテーションって仕組みも潜在能力は高そうですねぇ。何か構想を練られている、ということで、期待しておりますです。

2010-08-12 01:07:02
tomo🐧@learning @cocoatomo

@PG_kura ありがとうございます. 具体的な処理と人間に近いメタな情報を分離することで, どれだけソースが見易くなるか挑戦してきます.

2010-08-12 01:08:51
tomo🐧@learning @cocoatomo

@PG_kura とりあえず @range@notnull だけ作ってみました. http://tinyurl.com/2dgnwdn 裏の機構は無視して hoge と fuga の定義の部分をどのように感じるか教えてください.

2010-08-12 01:54:34
くっくっkura 🇯🇵🦀 @PG_kura

@cocoatomo 引数が複数ある場合に、引数がひとつのときと比べて可読性が変わりすぎてしまう可能性がちょっと気になります。

2010-08-12 01:57:42