ムービー中のlikeとwrapの説明は?だったので調べてみた
http://www.geekpage.jp/blog/?id=2008/2/29 は埋め込まれたムービーを基に書いているのですが、likeとwrapはムービーのプレゼンでの説明自体がES4仕様案と違う感じです。
の16,17,30ページがlikeやwrapの該当箇所です。まず、
というclassそのものを判定するisとcastオペレータがあります。
つぎに型の付加属性としてlike型とwrap型があります。
- like t型: 型名は無視し、構造上tとみなせる(look like t)構造であるなら型チェックを通す型
- wrap t型: 構造上tとみなせる構造であれば、その変数や式はt型のインスタンスであるとする型
これはコードの意味解析時(型チェック)でもチェックされる情報です。明らかに構造上違う型を渡すコードを書いたら静的な型チェックでエラーが出せるものです。
そういう構造をみる型に対応して、isやcastのようにランタイムでそれをチェックするオペレータが用意されています。
- o is like t: oが構造上tとみなせる型であればtrue、違っていればfalse
- o wrap t: oがt型ならo、oが構造上tとみなせるならoをtのインスタンスとしてラップしたインスタンス、oが構造上tとみなせないなら型エラー例外を投げる
仕様から確実に成り立つはずのケース
- var a : t → a is t
- var a : like t → a is like t == true
- var a : wrap t → a is t == true
- var a : like t → var b : wrap t = a; b is t == true
- (o wrap t) is t == true
- p = o wrap t → p wrap t === p
仕様案のあいまいなところ
なにがlook likeなのかは厳密にこの仕様案には書いてないのですが、以前 [id:bellbind:20071207:1197018213] でとりあげた
のほうにはES3での同等の判定をするコードがあり、それによると、like t型は「tのプロパティがすべてあり、そのれぞれの値の型が同じである」ような型のようです。この文書に従うなら追加プロパティがあってもlike tとみなせるようです。
また、wrapオペレータもこの文書だと、isに対応する is likeのように、castオペレータに対応するオペレータになっています。つまり、wrapでは(classでのcastのように)型チェックがあるだけです。
ムービーの日付は11/14、仕様案の日付は10/23、この文書の日付は11/29です。後者を信じるなら、プレゼン中やそこから引っ張った上記記事でのwrapのコードは型エラー例外が出るコードです。
ES4リファレンス実装も最近更新されたので、そちらに厳密に実装されているかもしれません。
実装es4-pre-release.M2(eval.smlのevalOperatorIsやevalOperatorWrap)では後者のドキュメントどおりでした。wrapは(VMであるmach.smlにある)Mach.Wrappedという形で特別に扱われるようになっていました。
型システム的に wrap S <: S <: like Sというようなサブタイプ関係があるようで、複雑だなあと思いました。キャストみたく、その前後でのバリアのように扱うのではだめなのかな。