理屈ではじめるjavascriptのポリモーフィズム

駆け足で進めるjavascriptのポリモーフィズム がズバ抜けてビューが多いので帰ってきたjavascriptのポリモーフィズム

// これはjavascript 2.0コードである
let x = t : T;
// 古い草案ではこう書いたのでこっちのほうが分かりやすいかも
// let x = t as T;

という式があった時、Tはtの型が何かという事を記しています。これを型注釈といいます。そして、javascriptがどのように型付けするかというと上記の例の場合ではtの型となり得る型の集合のうち尤もらしい型を選び出します。これを、制約型付けといいます。

上記の例ではなり得る型の集合の要素にはTが含まれておりtの型はTになります。これは型注釈が明示されているからです。ただし、javascriptはcurryなので型が正しいかは気にせず振る舞いを重視します。

さて、javascriptは型のある言語です。というか型付きラムダ計算を体系化します。上記の場合は型注釈によって型が明示されているのでどの型にすればよいか分かりますが、現行のjavascriptではこの様なことは出来ません。しかし、型付きであるので型がないといけません。

というわけで明示的にやっていた型注釈を機械に勝手にやらせてみます。それがjavascriptの暗黙の型変換です。暗黙の型変換は二つのことを行なっていて、一つはよく知られた必要なときに必要な型変換を行うこと。実はその前にもう一つ、束縛された時に型がわからないとどうしようもないのでこの型注釈を暗黙にやっています。

一言でいうと「型注釈がない式に最もらしい型注釈を付け足している」と言えます。

これを型再構築、またはよく知られた型推論と言います。ただしjavascriptでは推論した型が間違っていることもありえます
。これは「javascriptはcurryなので型が正しいかは気にせず振る舞いを重視する」こととは別の話です。なので推論が間違っていてもプログラムは動きます。しかも、振る舞いがあっていればそれは正しいプログラムです。

そして、この様な最もらしい型を選ぶ型推論アルゴリズムを一般化して「let多相」と言います。即ち、javascriptのポリモーフィズムはlet多相です。C++やjavaのポリモーフィズムは部分型多相といって別物です。

よく言われる、そして間違った解釈のポリモーフィズムという言葉は総じてこの部分型多相のことを指しています。ポリモーフィズムにはいくつもあってlet多相や部分型多相のほかにアドホック多相パラメタ多相というものもあります。アドホック多相はメソッドオーバーロードだったりより一般化されたマルチメソッド、パラメタ多相はいわゆるジェネリックスのことです。

一度まとめるとjavascriptは制約型付けなり得る型の集合/s>を付け足すという型推論を行う。この仕組を一般化してlet多相という。部分型多相であるC++とは違う。

だからjavascriptは始めから型推論在り来です。よって、暗黙の型変換はlet多相という型推論アルゴリズムの一種の実装と言えます。


そして、なり得る型の集合はどこで決められているかというとjavascriptでは仕様で決められています。一般的にはこのなり得る型の集合を抽象化してやれば自分で決められるのですが現行のjavascriptにはその手段がありません。

替わってjavascript2.0にはその手段が追加されていました──

type S = T;

として、Sを型変数と言います。Tは一つですが実際には要素をひとつ持つ集合です。これによってTを要素に持つなり得る型の集合を変数Sに束縛しています。

こうしてこのSを利用するには──

var x = t2 : S;

とすると変数xに束縛されたt2の型はSであるという型注釈が出来ます。
これを解釈するには実行時に型変数Sを見てその型の集合がどんなものかを覚えておきます。そして、Sを利用した型注釈が見つかるとSからTを要素に持つ集合が導出されて、このとき尤もらしい型はTであると型付けされます。型推論では型が正しいとは限りませんでしたが、今回はSからTを要素に持つ集合が導出され、t2の型がTであるという制約を受けるのでt2の型がTであることは正しいです。(プログラマが明示的に型注釈したからですね)

ただし、javascriptにとって型が正しいかどうかが重要ではないことには変わりありません。形注釈のできない現行のjavascriptが動作しているのは型より振る舞いが重視されるからですね。型を重視する言語ならこの様なことはありえないので奇妙かもしれませんがそういうものです。

実際のところ現行のjavascriptでも型タグを持っているので機械が勝手に追加する型注釈は型タグに一致します。それによってなり得る型の集合の要素には型タグが表す型T2を持ち、そこからt3の型はT2に制約され型が決定されます。

そして、javascriptの型は実行時にころころ変わるので状況に応じたなり得る型の集合が仕様で用意されていてそれに基づいて型が決まります。これとは逆になり得ない型になってしまうときはTypeErrorが投げられます。

なので型注釈がなくても普段は全く困りません。問題になるのは間違った型に推測されたとき、かつ振る舞いも一致しない時に動的言語なので実行してみないと分からないことの方です。

これはメソッドがオーバーライドされていた時に困るということです。だからモンキーパッチはやってはダメです。curryな言語で勝手に振る舞いを変えると正しいことが証明できなくなって破堤します。だから言語によっては型に後から別の振る舞いを追加するのを禁止してるわけですが……


ちなみにLiveConnectはこの型推論アルゴリズムをjavaを扱うときにまで拡張(適用)するものです。nashornはLiveConnectを実装していますがLiveConnectが拡張した変換ルールを満たしていないので型推論が間違っていると言えます。これは静的型付け由来なのでnashorn用のグルーコードを挿入する必要があり、互換性もありませんしあまり良いとはいえません。しかし、今のnashornはコールサイトの動的変更が実装されているにも係わらず使ってないので将来対応するかもしれないし実装対象外かもしれません。個人的にnashornは遅いことよりこちらのほうが問題だと思います。

関係ないけどnashornはJavaObjectだけじゃなくてJSObjectも持ってるんだよね。JavaFXにもJSObjectあるしJSR-223使う気無いよね(JavaFXはFXMLのハンドラ用scriptで使ってるはずだけど)。ディスられてるよね。そもそもJavaFXはJVM言語から呼び出せるのにFXMLのハンドラ用scriptに使うエンジンを選択する手段がユーザーにないよね。

特にオチなし

cernのページが復活したと聞いて

日経ソフトウェア7月号の

今回、綴るにあたって

このブログを綴るに相応しいネタを見つけた。
よって、至高のジョークにこれぽっちのユーモアを捧げる。


「そのコードは古い」javascript編が酷い。酷すぎる。

ゲイツの数々の名言やAOLの爆笑のものジョークの数々とは比べ物にならないほど酷すぎる。とにかく酷い。ポルナレフなんてそんなチャッチなもんじゃ断じてねぇ。
日本のwikipediaのwww関連の内容も相当出鱈目だがここまで酷いのはwebに触れて以来20年で初めて見た。
で、どこが酷いかと言うとpartpoint3の内容。恐らくこれを書いた人物の正体はジョン・タイターだろう。
あまりに酷いので内容は日経ソフトウェア7月号を読んでね(『最新「カッコいい」コーディング流儀』らしい)……と言う事にしてここからは我々の時間線の昔話をしよう。

はるか昔、銀河の彼方にnextstepという……さすがに遡り過ぎなのでmosaicくらいから始めようか。

LineBrowserが席巻していた時代は過ぎ去り、GraphicalBrowserの時代がやってきた。
その旋風を巻き起こしたのがmosaicというブラウザでこの頃はただHyperTextを表示するだけだった。

と言っても分からないだろうから現代語に翻訳するとWebBrowserがGUIになったという出だしにそして、昔はただネットワークでリンクされたテキストを表示するだけだったという話。

その後mosaicの開発チームが分裂してnetscape社ができてNNが出てきたわけだ。

すると、netscapeはwebを動的に変更しようと試みる。この技術の総称をDynamicWebと謳いそれに対応したServer製品をnetscapeは出していた。そこで新たに誕生したのが後のCGIというわけだ。
これはServer側でHyperTextに変更を加えて送信する方法だった……ところがこの方法はすこぶるServerに負荷をかけるので良くない。





ところで、今となってはServerに負荷をかけるなという話は知られた当たり前の話だが、では何故この様に言われるようになったか知っているだろうか?

それを説明するにはまずWWWWandererについて語らねばなるまい。WWWWandererというのはServerListを自動収集するエージェントの一種だ。このようなエージェントをWWWWCrawlerという。今では単にCrawler──Spiderとも呼ばれる──と呼ばれる類のエージェントだ。ServerListというのは今で言うロボット型検索エンジンのインデックスに相当する。

ただし、昔は手動で集めていて閲覧者が気に入ったWebPageをホストしているServerのURLを羅列していった。そうして出来上がったServerListを自分のServerにアップするわけだが、それを自動化するのがCrawlerの研究目的なんだけどその第一号がWWWWandererだったわけだ。

さて、WWWWandererがリストしたServerListのことをWandex(Wanderer + Indexの造語)と呼ぶ。WWWWandererはせっせとこれを収集していた──要するにロボット型検索エンジンの共通祖先だ──しかし、この収集の際のアルゴリズムが問題でWebPageが全部で300程度しかない様な時代に一つのpageに1日に頻繁に数十、多いと百回とかアクセスしてServerを落としまくっていた(昔のServerなんて今のマイコンボードの方がハイスペック)。だからServerに負荷をかけるなと言われるようになったのだ。


Serverに負荷をかけない方法となると次にnetscapeが思いついたのはクライアント側で変更する方法だ。なのでDynamicWebはクライアント技術へと変わっていく事となった。
その時生まれたのがDocumentObjectModel、略してDOMだ。DocumentModelだとかObjectModelだとかいうモデル化は何もDOMに限ったことではない手法だ……というのはその通りだが当時のMS信者のMS擁護材料でもあった。

ところでDOMはAPIだ。それを使う言語が必要になる。そこで──確か、生みの親もBrendan Eichだったはずだが──Brendan Eichがmocaを作った。これが後のLiveScript、更に後のJavaScriptだ。というわけでJavaScriptはDOMを扱うために作られた言語だ。標準化される前のDOMはjsのコアライブラリだった。1.4の頃DOM level1が勧告されたのでjsから外れて別仕様になった。

DOMと言えばNNとIEで互換性がない。というか正しくは標準を実装するまでIEはDOMじゃない。イベントハンドラの追加方法やドリブンが違うのは当たり前でAPIの命名を似せた程度の別物だからだ。E3戦略とは(良い物・既に受け入れられている物を)パクって(独自)拡張して(互換性をなくし)ユーザーを混乱させ、パクリ元は戦争をふっかけて亡き者にするというオペレーションだ。だから、ちょっと似せた別物であるのは戦略的に正しい。

それ以外に有名なのがinnerHTMLだろう。netscapeのDynamicWebはDOMを使い、DOMツリーにDOMオブジェクトを放り込んで構造をプログラマブルに扱いJSSで見た目をプログラマブルに扱った。替わってMSはinnerHTMLを使ってhtmlソースをそこに放り込むとhtmlを書き換えられた。MSはこれをDynamicHTMLと謳った。骨組みは似せて部分的に色々変えるのがE3戦略の要だ。だからDOMを使うことをDHTMLというのは間違いだ。

──折しも後世に伝わるブラウザ戦争の真っ最中だった。




なぜ、骨組みは似せて部分的に色々変えるのかというと骨組みを似せると見た目が似ているのでシェアを奪いやすい。そこに部分的に変えた互換性のなさと独自拡張でユーザーを囲い込むのを目的としている。幸いにもWIN95は売れた。それまではあんな糞OSがここまでシェアを伸ばすなんてDOS使いも3.1J使いも誰もが思ってはいなかった。WINとは昔はそういう扱いだった。精々週アスか月アスだったかが発売前に大騒ぎしたくらいだがフタを開けると売りにしていた互換性が名ばかりだったのでそれ以降は批判と似非互換性対策記事なんかがPC雑誌を賑わせていた。

そもそも過去の伝説のようにWIN95の販売日が語り継がれているが騒いでいたのはマスコミと秋葉くらいのもので既存のDOS、WINユーザーはアスキーを読みながら「所詮はWIN、見た目が変わっただけで何かやらかす」と踏んでいた。それか、エヴァすげー! テイルズすげー! と言っていた頃合いだ。恐竜惑星面白い!と言っていた頃かもしれない。エヴァ暗い! DQ6買ったたった! と言っていた口なので正確にはどの時期かは覚えていない。HotWiredくらいは覚えている──。

しかし、その当時PCを触った事のなかった層に売れた。PCを持っていないにもかかわらず訳もわからず買って行くほど売れた(海外はどうか知らない)。とにかく秋葉とマスコミはお祭り騒ぎだった。

更にMSはIEをシェルに統合するという暴挙に出た。シェルが重たくなったので結構文句も出たがその転機がOSR2だ(いまでいうSP)。それまではオプションだったのでそもそもOSがHTTPすらサポートしていない。このとき生まれたのがゲイツのあの伝説の名言だ(何かは言及しない、だって自分で調べたほうが面白いだろ?)。しかし、名言とは裏腹にメーカー製PCにはNNがバンドルされ、そうでなければ必ずライセンスを買っていた。mosaicからの移行先として耐えうるものがwinには他に無かったというのもあるが、世界は既にwwwの大流行だったからだ。ちなみに日本はその頃パソ通が大流行。

そして、ゲイツは先を見る目は無いが方向転換は超早い、コンコルドのごとく早い。こうしてOSR2からHTTPの標準サポートとIEのシェル統合へと舵を切ったわけだ。ゲイツの先見性のなさはいつもの事で見る目が無いとよく批判されたものだし、所詮は使いものにならないIEだったのでいままでPCを触った事のなかった、今までwwwに触れたことのなかった層以外は見向きもしなかったわけだが……ちょうどその頃、netscapeは名指しで宣戦布告されブラウザ戦争開戦という危機に立たされた。それに焦ったというのが通説だがNN4は中途半端にリリースを早められバグだらけで酷かった。ただでさえそれまで冷戦状態でbrowserのリリースが早かったのに宣戦布告で焦ったからだろう。この時ばかりはIEに疎開したりする人達もいたものだ。


DOM level1以前はdocument.write()でせっせとhtmlを吐いていた。なぜならIEには別物が載っていてIEでは互換性がなかったからだ。比較的これはメジャーだった。あまり知られていないが画像とかhtml以外も吐ける。

DOM level1、つまり標準化以降はDOMを使うようになっていった……というと、そうではない。IEではinnerHTMLにソースを放り込み、NNではlayer要素+DOM+JSSを使っていた。

先にも出てきたようにlayer要素以前からNNではDOM+JSSは使われていたのだが、ところでJSSを知っている閲覧者はどのくらい居るだろうか? むしろバリバリ使ってゲーム作ってたよという御仁ならば貴方は同志であり、戦争を共に生き残った戦友でもある(ブラクラの様に重いテトリスとか作ったり、AI組んでPCをハングアップさせたものだ)。

JSSとはJavascriptStyleSheetの略でスタイルシートの一種である。スタイルシートといえばViolaWWWのスタイルシート……え? CSSだって? 残念ながら昔のNNはCSSをJSSに変換していたのでCSSは持ってない。世に言うNN4である!

たしかIEはdraftあたりのCSSを先行実装と独自拡張して持っていたけど時代はhtmlにalignとかfontとか書く時代だったのであまり普及してなかった。スタイルシートを使いたくてもIEは仕様満たしてないしNNは持ってないし、javascriptのonloadハンドラでIE用とNN用のソース分けたりもした。

WYSIWYGなんて何でもかんでもanchor使いまくって酷かったしIE以外まともに表示されなかったし、そもそもWYSIWYG使ってた連中はHTMLのHの字すら知らなかったから商用サイトはWYSIWYGの吐いた酷いコードが蔓延していた。95祭りで入ってきた人達はこういうソースを読んで手書きしていたので更に酷かった。さらにこういう人達がhtmlの解説を始めるからもはや終末戦争だった。WYSIWYGがまともなコードを履くようになるのはもう少し先の話である。

この頃にはWIN95OSR2のIE抱き合わせとNN4の大恐慌でブラウザのシェアはIEに逆転されてしまっていたのでヒトラーが現れるんじゃないかというほどひどい有様だった。IE以外まともに表示されないといったが、それは間違いである。IEですらまともに表示されないしクソ実装のせいで仕様すら満たしてないし、独自拡張乱立でヒャッハーな時代だった。私はイヤッハー可愛いほうが好きだ。

ActiveXObjectのXmlHttpRequestが出てきたのはこのくらいでNNのLiveConnectに対抗してActiveXを触れる様にしたしたのが始まりだ。NNはjsからプラグイン叩けるようにしていたのでjsからFlash制御したり出来たけどActiveXObjectもLiveConnectも普及することはなかった。

えっと──まだ説明してないlayer要素についても話しておこう。layer要素というのは要素の上に要素をオーバーラップするための要素だ(CSSがまだ要素のオーバーラップができない頃からあった)。これをJSSで見た目いじってDOMで操作してとjsを駆使する前提の要素だが、要するに今で言うCanvas要素だ。やってることは変わらない。layerに入れ子にしたコンテントをDOMとjsコードによってポップアップ表示させたWidgetとかそういう使い方をするためのものだ。HTML5とも何も変わらない。ただし、IEはlayerもJSSも持ってないのでIEでは当然動かない。UA見てIE用の静的なhtmlに飛ばすのがlayerをフル活用したpageの常だったので見たことある方が少ないんじゃないだろうか。

まあ、一般的にはまだ、jsの遅さにイライラするかFlashに巻き込まれてクラッシュしてイライラするかの頃の時代だった。IEのDOM実装が超遅かったりjavaアプレットテロに巻き込まれたり、イライラする要素はなんでもあった筈だ。作ってる方からするとIEのDOMが遅いことよりPNGが使えないほうが困ったもんだ。

さて、そろそろ世の中はWIN98が発売されるかその後くらいだ。まだ98SEなんてものはない。

大体このくらいにあのNN5が登場した。そう、登場したのだ……。

WinMainからして間違っててさ、あとJavavigator Projectというのがあってだね──Rhino誕生の瞬間ですよ。rhinoは忘れ去られたままプロジェクトは凍結されましたとさ、めでたしめでたし。忘れ去られたからこそ凍結されてもソースコード破棄されなかったんだよ。

それからNN5のコンパイルに挑戦する強者共を切り捨てて作りなおすとか言われても……。

かくしてNN6の時代到来、Mozilla Internet Suitsです。IEは5だっけ? この頃になるとHTML4+DOM+CSS+JSなわけだけどIEの互換性の無さ無さ無さ! 標準化仕様ってなんだろうね。まあ、まだまだHTMLに全部埋め込んでたような時代。NNはソースコード変わった辺りから徐々に独自拡張を取っ払っていてlayerとかJSSとか使えなくなった頃。

NN4とは違うのだよっ! NN4とは!

でもNN6.2より弱いんでしょ?

この時代はだいたい、operaの登場から2年くらい。当時は第三のブラウザとか早いとか持て囃されたけど2kくらいの頃からロースペック御用達とか言われる始末でjs2.0御三家の一人なのに影が薄かったりなんだり。

そして、Mozilla Internet Suitsからブラウザ・コンポーネントを独立させたのがPhoenix。後のfirefox。OSでいうとWinはXP、linuxは忘れたmacは9かな。

ここら辺までたどればそろそろ知られた時代になるはず。タイターの世界の歴史とは大きく異なるはず──そういえば何の話だったかと考えたらそうそう、日経ソフトウェア7月号の「そのコードは古い」javascript編partpoint3が酷い、だった。いつもユーモアを忘れないAOLのジョークもなんのその、非常に素晴らしい出来のジョークだ。イグ=ノーベル賞をあげちゃいたいくらい。

さて、いつものように大事なことなので繰り返しますが──

DOMはnetscapeがHyperTextを動的に変更するために作り、MSがE3戦略の元、互換性のない形でパクったせいで標準化する羽目になったAPIでJavascriptはその為に作られました。
このブログは世界一誤解されたjavascriptの誤解を解き明かすブログです。

今回の件は誤解どころが出鱈目に近いですが、この記事を書くキッカケをくれた日経ソフトウェア7月号の記事にありがとう! そして、ありがとう!

メッセージ送信とrhinoでjavafx

JavaFXのスタートアップ諸々には作法がある(静的な型情報を用いたリフレクションを多用)ので動的なJVM言語でスクリプトを書くと起動でコケるはず。

これは静的な型と言うことは実行時にJavaFXの型にコンパイルされていれば問題ないが、本来、動的言語がいつコンパイルするかは不定なので動的言語とは本質的に相性が悪い。

rhinoの場合はJavaAdapterでは不適切でjscでjavafx.application.Applicationを継承してAOTコンパイルすれば良い。

ではなぜJavaAdapterでは不適切かというとJavaAdapterはJavaObjectを返す内部[[Construct]]メソッドを持ったオブジェクト、要するにコンストラクタ関数だからだ。

JavaObjectとはJSObjectと並
ぶnetscape伝統のjavaからjavascriptを操作するオブジェクト群で、JSObjectはjavaからjsを──JavaObjectはjsからjavaを扱うためのプロトコル。
で、JSObjectは割愛するとしてJavaObjectがどうやってJava(のオブジェクト)を扱っているかというと単にメッセージ送信を行なっているだけ。ただし、jsのオブジェクトはjavaのオブジェクトが持っているメソッド群を本来は持ち合わせていないため、固有の内部[[Get]]、[[Put]]/[[Set]]の振る舞いを持ってメッセージ転送を行なっている。javascriptでメッセージ転送というと__noSuchMethod__だが、これはesどころかjsの仕様にすらないspidermonkeyの独自拡張。だから__noSuchMethod__を定義しているわけではなく直接、内部[[Get]]、[[Put]]を変更している。

ただし、メッセージ送信とメッセージ転送は別物なので注意。jsは元からメッセージ送信を持っているが仕様ではメッセージ転送を持っていないので存在しないメッセージを扱うためにメッセージ転送を行うよう内部[[Get]]、[[Put]]を変更する必要がある。

この様に内部の振る舞いを変更するというのはMOPの手法なのでJavaObjectは二種類の方法を用いてjavaを扱うという問題を解決していることになる。メッセージ送信が正しく行われるならメッセージに対応する関数が存在するということなので、即ち正しくメソッドサーチされるということ。


メッセージ送信は実行時に行なわれるものなのでそれがjavaのオブジェクトでなくても(つまり、javaの型じゃなくても)実行時にjavaのメソッドを発見出来れば良い──メッセージ転送によって存在しないメッセージを正しく送信出来ているのでこれは成功する。javaのメソッドを発見出来なければそれは単にメソッドサーチに失敗するだけ。その場合、LiveConnectがエラーを通知する。


さっきから静的な型だとか動的言語だとか言っているが実はこれは正しくない。
なぜなら動的言語でも静的な型を持っているからだ。動的言語の「動的」とは型が実行時に柔軟に変わるという意味で「弱い型付け」とか「強い型付け」の強弱とはこの挙動を指している。だからV8が暗黙の静的な型を持っているという趣旨の言い方は間違っている。
モノタイプでなければ動的言語が静的な型を持っているのは当たり前だからだ。おそらく"静的な"型という言い方がややこしい。動的に変換されるの方がふさわしい。V8は動的に変換する必要のない型をそのままで扱っているだけだ。これがjavascriptにおけるアーリーバインディングの正体だ。アーリーだのレイトだの関係なしに動的言語なのだから"実行時に"変換する必要のない型をただ変換せずにそのまま扱っているに過ぎない。実行時の情報を用いるのが動的言語の特徴なのでこれは自然なことでjavascript2.0やAdobeのes4RIでもvar foo : Number;とかvar foo as Number;とすることで出来た。

今のjsにこれがないのは型が静的だとか動的だとか関係なしに常にリロードされる可能性のあるブラウザにおいてアーリーバインディングとレイトバインディングの混載が非常に面倒だからTC-39では入れないと決定しただけ。js仕様の問題ではなくブラウザの都合を優先した結果だ。


ブラウザの場合リロードされる度にキャッシュされたマシン語のチェックと再コンパイルが発生するしリロードされる度に状態が変わる変数はキャッシュが必ず無効になるのでいちいち型推論してまでアーリーバインディングした上で早々とマシン語にしてキャッシュするメリットが薄い。型推論とキャッシュとコンパイル作業は充分遅いからブラウザでの実行速度にこだわるTC-39には仕様にアーリーバインディングがない方が早い実装が作れるからそっちの方が都合が良いということ……結局どの問題もここに行き着く。


最初に言った実行時にJavaFXの型にコンパイルされていれば問題ないというのは表現形式の変換だけではなく型変換も行なわれているからだ。つまり最終的にJavaFXを使う直前までにJavaFXの要求する型になっていれば良いので型変換のタイミングは重要ではない。ただ、javaのinvokedynamicのような仕組みがなければコンパイルした時点で型が固定されてしまうためこれは動的言語らしくない。




rhinoのJavaAdapterは最終的に表現形式は変換されるが型はJavaObjectなのでjavafx.application.Application#lunch(Class)に失敗するというカラクリ。

rhinoはかなり素直に動的言語として実装されている。