JavaScriptで型が書けるDSLを提供するdeftypes.js作った
こじらせJavaScriptシリーズです。
mizchi/deftypes.js https://github.com/mizchi/deftypes.js
主にcoffee-script用のDSLです。以下すべてcoffee。
ブラウザ
<script src="https://raw.github.com/mizchi/deftypes.js/master/deftypes.js"></script> Deftypes(); //provide DSL
Node
npm install deftypes
概要
型が書けます。残念ながら動的チェックです。
Point = {x: Number, y: Number} p1 = def Point, {x:1, y:2} #=> {x: 1, y:2} p2 = def Point, {x:1, z:2} #=> type error
defとTがDSLです。オプションで何もせずにインスタンスを返却するだけするモードもあります。これによってパフォーマンスを落とすことなく、型を明示的に宣言しながら開発することができます。(その際のオーバーヘッドは型情報の宣言のみで、ほぼ無視出来るでしょう)
Nullable型
NullableNumber = {n: T.Nullable(Number)} p1 = def NullableNumber, n:1 p2 = def NullableNumber, n:null
配列
number_list = def [Number], [1,2,3]
関数型
f1 = def T.Func([Number, Number], String), (m, n) -> "#{m}, #{n}" f1(1,2) #=> "1, 2" f1("",2) #=> argument error
引数と返り値の型を動的にチェックします。違反が検出されたら例外をthrowします。
型宣言されたインスタンスを変更するとき、専用の高階関数の中で副作用をだすようにすれば、高階関数を抜けた時にも型チェックをすることができます。
p = def Point, {x:1, y:2} def Point, p, -> @x = 3 # Type Error def Point, p, -> @y = "not number"
やや面倒ですが、副作用を出すという危険な行為は面倒臭くしておきたいのです。
これを無視してブロック外で行われた変更は検出しません。実装上は検出できるけど、このライブラリ専用の挙動が増えすぎるのでまだ避けてます。
それ以上の詳しくはREADMEとテストコードをみてください。
用途
静的解析ではないので、テストコードを書いたりしてカバレッジあげないとあまり意味がありません。むしろテストコードでの型チェックに使うといいかもしれません。
型をコード中に定義して文芸的プログラミングな文脈で可読性をあげる目的もあります。これは個人的な目的です。