• 検索結果がありません。

DolittleからJavaScriptへのトランスパイル実行

N/A
N/A
Protected

Academic year: 2021

シェア "DolittleからJavaScriptへのトランスパイル実行"

Copied!
6
0
0

読み込み中.... (全文を見る)

全文

(1)

Dolittle

から

JavaScript

へのトランスパイル実行

本多 佑希

1

長 慎也

2

大村 基将

1,3

久野 靖

4

兼宗 進

1 概要:Dolittleはプロトタイプ方式のプログラム言語であり,Classを定義せずにオブジェク トを扱えることから,中学校から大学などの多くの授業で利用されてきた.DolittleはJava で開発され,JavaアプレットによりWebでの実行も可能である.教育利用においてはイン ストールせずにWebブラウザから手軽に利用できることは重要な要件である.しかし,Java アプレットでは実習用の計算機にJavaをインストールしたりアプレットの実行を許可した りする設定を管理者権限で行う必要があり導入の障害になってきた.そこで,CoffeeScript

やTypeScriptなどのAltJSと同様に,Dolittleで記述されたプログラムをJavaScriptに動 的に変換(トランスパイル)して実行する方式を採用することで,Webブラウザから手軽に 利用できる環境を実装することにした.DolittleとJavaScriptの双方には,プロトタイプ方 式であること,オブジェクトの実体がハッシュであること,動的型付け言語であること,メ ソッドを手続きオブジェクトの代入により定義することなど,多くの共通点がある.また, トランスパイラとして実装することにより,Dolittleのプログラムを実行できることに加え, JavaScriptの各種機能をDolittleから呼び出して利用することが可能になった. キーワード:Dolittle JavaScriptトランスパイル コンパイラ

1.

はじめに

Dolittle1, 5)は教育用に設計された言語である. JavaScriptのようなprototype方式のオブジェク ト指向を採用することで,クラスやインスタンス などの概念を意識せず,オブジェクト指向を学ぶ ことができる. 教育利用においては,ローカルにインストール することなくWebブラウザから実行できること は有用である.DolittleはJavaで開発されている 1 大阪電気通信大学

Osaka Electoro-Communication University

2 明星大学 Meisei University 3 静岡大学 Shizuoka University 4 筑波大学 University of Tsukuba ことから,JavaアプレットによりWebブラウザ で実行することが可能であった.しかし,近年で はJavaの実行環境を用意することが容易ではな くなってきたことから,JavaScriptで実行できる Dolittleの実装を検討することにした. 実装にあたっては,JavaScriptでインタプリタ を実装することも考えられたが,今回は Dolit-tle と JavaScriptの 言 語 的 な 類 似 点 に 着 目 し , TypeScript2)CoffeeScript3)等のAltJSと同様 にDolittleをJavaScriptに変換して実行するトラ ンスパイル(source to source compile)する方式 を採用した.

本稿ではある言語で書かれたプログラムを,抽象 化レベルが同程度の別の言語に変換することをト ランスパイルと呼ぶ6)TypeScriptJavaScript に静的型付けやモジュールといった概念を付加

(2)

しており,CoffeeScriptはJavaScriptにクラスの 概念や構文の簡潔さを付加している.本研究では JavaScriptに「プログラミング初学者でも扱いや すい」「教育利用に適している」といった,Dolittle の特徴を付加することを目的とする.

2.

Dolittle 言語とその実装

図1にDolittleの基本構文を示す4, 7).基本的 な構文は代入とメッセージ送信であり,簡潔に記 述できることが特徴である.この章では,Dolittle の言語仕様について述べる. プログラム::= (文 ’.’)… 文::= [変数’=’ ]式 変数::= [項’:’ ] 名前 式::=単純式|送信 送信::= [項] ’ !’ 電文 電文::=単純式 … 名前( [’;’]単純式 … 名前)… 括弧::= ’(’中置式’)’| ’(’送信’)’ 単純式::=数値定数|文字列|括弧|ブロック ブロック::= ’[’ [ ’|’名前…’|’ ]文( ’.’ 文)…’]’ 中置式::=中置式 演算子 中置式|項 項::=単純式|名前 図1 Dolittleの基本構文 2.1 メソッド実行 Dolittleのメソッド実行(メッセージ送信)の例 を示す. obj ! 100 (x) (x+2) msg. objはオブジェクト,100と(x)と(x+2)はパラ メタ,msgはメソッド名である.変数名と中置式 をパラメタに含める場合は括弧で囲んで記述する. メソッド実行はカスケードすることができる. obj ! msg1 msg2. 上の例は次の例と等価であり,objにmsg1を実 行した戻り値に対して,msg2が実行される. (obj ! msg1) ! msg2. 2.2 ブロック ブロックはコードを内包するオブジェクトであ り,生成されたときの環境を保持している. ブロックは単独で実行されるほか,オブジェク トのプロパティに代入することでそのオブジェク トのメソッドとして扱われる.また,後述するよ うに,条件分岐や反復などの制御構造を記述する ために用いられる. 次の例は,ブロックを実行する. [...] ! execute. 次の例は,ブロックを10回実行する. [...] ! 10 repeat. 次の例は,オブジェクトobjのmsgというプロ パティにブロックを代入することでメソッドを定 義し,それを実行している. obj:msg=[...]. obj ! msg. 引数は,次のようにブロックの先頭で取得する. blk = [|x y| ...]. blk ! 100 200 execute. 繰り返しの場合は,何回目の実行かというカウ ンタの値が渡される. [|n| ...] ! 10 repeat. 2.3 条件分岐 Dolittleにはifやwhileのような制御構文はな く,ブロックを用いたメッセージ送信のカスケー ド実行で制御構造を表現する. [...] ! then [...] execute. [...] ! then [...] else [...] execute. これらは次のように実行される. ([...] ! then) ! [...] execute. (([...] ! then) ! [...] else) [...] execute. ブ ロ ッ ク に then が 適 用([...] ! then が 実 行 )さ れ る と ,条 件 の 成 否 等 に よ っ て True/False/Doneの中間オブジェクトが返る. • True ! [...] execute は引数のブロックを実行する. • False ! [...] execute は引数のブロックを実行せずundefinedを 返す. • True ! [...] else

(3)

は引数のブロックを実行し,ブロックの実行 結果を内包したDoneを返す. • False ! [...] else は引数のブロックを実行せずTrueを返す. • Done ! [...] execute は引数のブロックを実行せず,自身が内包し ている値を返す. 2.4 オブジェクト間の継承 Dolittleはクラスではなくプロトタイプを用い てオブジェクト間の継承関係を持つ.rootはす べてのオブジェクトの親(プロトタイプ)であり, number, string, blockなどのオブジェクトがあら かじめrootの子として定義されている.

プログラム中でcreateを実行してオブジェクト を生成した場合,元のオブジェクトobj1は生成さ れたオブジェクトobj2の親になる.

obj2 = obj1 ! create.

定数や,計算結果などで暗黙的にオブジェクト が生成された場合は,stringやnumberなどのプ ロトタイプオブジェクトが親になる. str = "abc". x = 1 + 2. 2.5 プロパティの継承 オブジェクトのプロパティを参照した場合,そ のオブジェクトに該当するプロパティが存在しな い場合は親のプロパティを参照し,存在しない場 合はさらに祖先のプロパティを参照していく. メソッドもプロパティにブロックを代入する形 で定義されているため,同様の探索が行われる. すべてのオブジェクトの親はrootであるため, rootのプロパティはすべてのオブジェクトから参 照可能なグローバル変数として扱われる.次の代 入は,すべてrootのプロパティ「x」を定義する. root:x = 3. :x = 3. x = 3. 2.6 対応しているオブジェクト 表1に,現在JavaScript版で実装しているオブ ジェクトと定義されたメソッドを示す. • arrayオブジェクトは,Arrayをラップした ラッパーオブジェクトである. • stringオブジェクトは,String.prototypeにメ ソッドを追加し,メソッド拡張を行った. 表1 対応しているオブジェクトの例 オブジェ クト メソッド 説明 array create 配列を生成する size? 要素数を返す get 要素を参照する add 要素を追加する join 要素を連結した文字列を返す removepos 要素を削除する insert 要素を挿入する foreach 各要素に対してメソッドを実行する string add 文字列を連結する contain? 文字列が含まれているかを調べる timer create タイマーを生成する interval 実行間隔を指定する times 実行回数を指定する execute タイマーを実行する block then ブロックを評価し中間オブジェクト を返す repeat ブロックを指定回数実行する while ブロックを繰り返し実行する execute ブロックを実行する

3.

トランスパイラの設計と実装

3.1 トランスパイルの方針 1 章 で 述 べ た よ う に ,今 回 は Dolittle を JavaScript で実装するために,インタプリタを 作成して実行する代りに,JavaScriptへのトラン スレータを作成して実行する方式を採用した. DolittleとJavaScriptは,構文は異なっている が,言語仕様には類似する点が多い.これらの性 質を利用することで,JavaScriptでの実行が容易 に実現できると期待した. プロトタイプ方式である オブジェクトの実体がハッシュである 動的型付け言語である メソッドを手続きオブジェクトの代入で定義

(4)

できる グローバルなオブジェクトは,あるオブジェ クトのプロパティである 関数(ブロック)は,実行された外側のスコー プを持つ 3.2 トランスパイルの実装 3.2.1 ブロックの変換 ブロックは,JavaScriptの匿名関数を用いて実 装を行った.Dolittleにおいてのブロックは実行 されたスコープを自らのスコープとして持つ.こ れは,JavaScriptの匿名関数においても同様の動 作をする.宣言時には実行されない点も同様であ る.図2と図3に,ブロックとメソッドの変換例 を示す. // Dolittle [100]. [|param| param + 100]. [|param; local_param| local_param=100. local_param+param ]. // JavaScript (function(){return 100;});

(function(param){return param!100 add;}); (function(param){ var local_param; local_param=100; return local_param+param; }); 図2 ブロックの変換 // Dolittle obj ! 100 (param) "str" msg . obj ! [func] msg. // JavaScript obj.msg(100,param,"str"); obj.msg(function(){return func;}); 図3 メソッドの変換 3.2.2 継承の実装 親子関係は,JavaScriptのprototypeを利用し た.createメソッドが実行されると,Object.create を使用し,自分を親とする子オブジェクトを生成 し,返す.親のプロパティを探しに行く仕様は, JavaScriptのprototypeチェーンを利用すること で対応した. 3.3 制御構造の実装 3.3.1 条件分岐 条件分岐は,JavaScriptのFunction.prototype にthenメソッドを追加し,Functionオブジェク トのprototype拡張を行うことで対応した.then メソッドを呼び出し,カスケードすることで条件 分岐を行う. 3.3.2 繰り返し 繰 り 返 し に 対 し て も ,JavaScript の Func-tion.prototypeにrepeatメソッドを追加し, Func-tionオブジェクトのメソッド拡張を行うことで対 応した.繰り返し文では,引数として渡された回 数分,呼出し元のブロックを実行する.その際に は,呼出し元のブロックに繰り返し回数を引数と して与える.呼出し元のブロックで引数を指定し ている場合,この繰り返し回数を引数として取る ことができる.

4.

議論

いくつかの機能に関しては,言語仕様の違い等 の理由から,互換性について検討を行っている. 4.1 タイマーオブジェクトの互換性 Dolittleのタイマーオブジェクトの繰り返し実行 は,スレッドにより実行される.しかし,JavaScript にはスレッドが存在しない.本研究で実装したタ イマーオブジェクトの繰り返し実行も,JavaScript のsetInterval関数を用いて実装したため,スレッ ドでの実装にはなっていない. Dolittleのタイマーオブジェクトには,waitメ ソッドが存在する4, 5).これは,呼び出し元のタイ マースレッドが処理を終えるまで,メインスレッド の動作を止めて待ち合わせる.しかし,このwait

(5)

メソッドをJavaScriptで実装することは困難で ある. そこで,「タイマーの終了までメインスレッドを 止める」のではなく,図4のように「タイマーの 終了時に実行するメソッド」を指定する機能を提 供することで,実用上はwaitに近い用途を実現す ることを検討している.

clock = timer ! create. clock ! [...] execute. clock ! wait.

label ! ”hello” create. clock = timer ! create. clock ! [...] execute.

clock ! [label ! ”hello” create] after ececute.

4 タイマーのwaitの対応 4.2 prototype汚染 JavaScriptにおいて,Functionオブジェクトや Stringオブジェクト等のprototypeにメソッドを 追加してメソッド拡張を行うことはあまり良いも のではないとされている.この問題は,ラッパー オブジェクトを設計し,提供することで解決が可能 である.しかし,その場合はトランスパイルが複 雑になってしまう.そのため,本研究ではメソッ ド拡張を行うことにした. 以下に,Functionのprototypeを拡張した場合 と,ラッパーオブジェクトを実装した場合の,ブ ロックのトランスパル例を示す. トランスパイル前 // Dolittle obj:func=[|param| self:myField ]. トランスパイル後 // JavaScript:prototype拡張 obj.func=(function(param){ return this.myField; })); // JavaScript:ラッパー obj.func=(new Block(function(param){ return this.myField; })); 上のobj.funcを呼び出す文は以下のようにトラン スパイルされる. トランスパイル前 //Dolittle obj:func!(param) execute. トランスパイル後 //JavaScript:prototype拡張 obj.func(param); //JavaScript:ラッパー obj.func.execute(param); この呼び出しは,Blockオブジェクトにexecuteメ ソッドを追加しておくことで実現可能である.し かし,Dolittleにおいては,次の例のような方法で もメソッドを呼び出すことができる. //Dolittle obj!(param) func. これをJavaScriptにトランスパイルする場合, pro-totype拡張とラッパーを用いた場合では次のよう にトランスパイルの方法を変える必要がある. // JavaScript:prototype拡張 obj.func(param); // JavaScript:ラッパー obj.func.execute(param); しかし,ラッパーを用いた場合には次のような問 題がある.

• executeに渡されるthisの値がobjではなく,

obj.funcになってしまう. • obj.funcが本当のFunctionオブジェクトの場 合は実行できなくなる(つまり,Functionオ ブジェクトをすべてラップをする必要がある. JavaScriptから生のデータを受け取るのが難 しくなる.) これらの問題を考慮して,Functionオブジェクト ではprototype拡張を行うことにした. ただし,他の組み込みオブジェクトに関しては prototypeの拡張は可能な限り行わず,ラッパーを 作成することを設計の指針としている. 例えば,配列についてはJavaScriptのArrayク ラスを直接利用するのではなく,ラッパーを作成 した.理由としては次のような点が挙げられる.

(6)

• JavaScriptの配列は,要素の添字が0から始 まる(0-originである)が,ドリトルの配列は, 1-originである.このため,Arrayクラスの メソッドを拡張してしまうと,添字の仕様が 0-originのものと1-originのものが混在して しまう. ドリトルにはJavaScriptにおけるa[i]のよう な,配列の要素にアクセスするための特別な 構文がなく,単なるメソッド呼び出しで要素 にアクセスするため,ラッパーの実装が簡単 である. このような,組み込みオブジェクトの性質を踏ま えて,ラッパーを利用するかprototype拡張をする かを臨機応変に採択する方針で設計を進めていく.

5.

現状と今後の対応

5.1 実装の状況 DolittleをJavaScriptにトランスパイル実行す ることで,言語仕様のコア部分を実装することがで きた.性能は,基本的なベンチマークでは,Firefox, Chrome等の代表的なブラウザで実用的な速度で 動くことを確認した.今後は,グラフィックスや GUI部品などのUI関係の拡張を行う予定である. 5.2 JavaScriptで実行することの利点 DolittleをJavaScriptで実装したことで,端末 にJavaやDolittleをインストールすることなく, 手軽にWebブラウザで実行できるようになった. これは教員や生徒が端末へのインストールを許さ れていない一般的な学校において大きな利点にな ると考えている. DolittleからJavaScriptを呼び出して使えること も利点になる.今後は,DolittleからのHTML/CSS 等を生成する機能も検討したい. 5.3 プログラムの保存方法 Webブラウザでプログラムを記述した場合,作 成したプログラムを保存する方法は検討が必要で ある.ひとつはWebブラウザ内にWeb Storage として保存することが考えられる.同じ端末で実 行する必要があるが,容易に実現できることが利 点である.もうひとつはサーバー側でファイル保 存機能を提供することが考えられる.これについ ては,個人利用の場合はID登録や認証,学校利用 の場合は教員の登録や授業ごとの管理などが必要 になる可能性があり,引き続き検討を行う予定で ある. 5.4 I/Oについての検討 JavaScriptから,周辺装置やネットワーク,OS などへのアクセスについては引き続き検討が必要 である.ローカルファイルへのアクセス,サーバー との通信,MIDI等を利用した音楽演奏,接続した センサーやロボット等の外部機器との通信などは, 今後の検討が必要になる.

6.

おわりに

DolittleのプログラムをJavaScriptにトランス パイルする,トランスパイラを実装した.このトラ ンスパイラを使用することで,Dolittleのプログラ ムをWebブラウザで動作させることが可能になっ た.また,Dolittleのプログラムから,JavaScript の各種機能を使用できることになった. 本研究を進めることで,Dolittleは,より教育現 場に適したプログラミング言語になる.そのため, 4章で述べた問題点の解決に努め,改良を進めて いきたい. 参考文献 [1] プログラミング言語「ドリトル」. http://dolittle.eplang.jp/ [2] TypeScript : http://www.typescriptlang.org/ [3] CoffeeScript : http://coffeescript.org/ [4] 兼宗進,御手洗理英, 中谷多哉子, 福井眞吾, 久 野靖.学校教育用オブジェクト指向言語「ドリト ル」の設計と実装.情報処理学会論文誌, Vol.42, No.SIG11, pp.78–90, 2001. [5] 兼宗 進,久野 靖,ドリトルで学ぶプログラミン グ[第2版], 2011. [6] スティーブ・フェントン, TypeScript実践プロ グラミング, 2015. [7] 兼宗進,久野靖.プロトタイプ階層を持つ教育用 オブジェクト指向言語「ドリトル」.コンピュー タソフトウェア, Vol.28, No.1, pp.43–48, 2011.

参照

関連したドキュメント

スライダは、Microchip アプリケーション ライブラリ で入手できる mTouch のフレームワークとライブラリ を使って実装できます。 また

LLVM から Haskell への変換は、各 LLVM 命令をそれと 同等な処理を行う Haskell のプログラムに変換することに より、実現される。

このように、このWの姿を捉えることを通して、「子どもが生き、自ら願いを形成し実現しよう

全国の宿泊旅行実施者を抽出することに加え、性・年代別の宿泊旅行実施率を知るために実施した。

• 競願により選定された新免 許人 は、プラチナバンドを有効 活用 することで、低廉な料 金の 実現等国 民へ の利益還元 を行 うことが

3.仕事(業務量)の繁閑に対応するため

据付確認 ※1 装置の据付位置を確認する。 実施計画のとおりである こと。. 性能 性能校正

□ ゼミに関することですが、ゼ ミシンポの説明ではプレゼ ンの練習を主にするとのこ とで、教授もプレゼンの練習