ムービー中のlikeとwrapの説明は?だったので調べてみた

http://www.geekpage.jp/blog/?id=2008/2/29 は埋め込まれたムービーを基に書いているのですが、likeとwrapはムービーのプレゼンでの説明自体がES4仕様案と違う感じです。

の16,17,30ページがlikeやwrapの該当箇所です。まず、

  • o is t : Javaでいうo instanceof t
  • o cast t : Javaの (t) o

という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というようなサブタイプ関係があるようで、複雑だなあと思いました。キャストみたく、その前後でのバリアのように扱うのではだめなのかな。