作りたいもの: プログラミング言語のコア概念を学ぶサイト

増井さんの作りたいものリストを作ろうというスライドを見て「確かに『いつかやる』リストに入れてるだけじゃ発展しないから、公開しても問題ないものは公開したらいいなぁ」と思ったので早速やってみました。とはいえ、僕の『いつかやる』リストは一つのリストの要素に色々な設計やアイデアが書かれていて、全部一度に載せると読むのも大変。とりあえず1つ目だけ載せてみます。動機なんかを加筆。

プログラミング言語のコア概念を学ぶサイト

日本語や英語で書かれた解説を読むより、実際に動かしてみたほうがわかりやすいこともある。


しかし、広く使われている言語は既に長年の改良が繰り返されていて、改築・増築を繰り返した老舗旅館みたいに複雑なものになってしまっている。


学習のために、小さくシンプルな、全体像を理解しやすい、わかりやすく可視化された「言語の実装」が必要だ。

そんなものはすでにあるのでは?

かつて色々な方法で(Javaアプレットで、Flashで、etc)、色々なアルゴリズムの可視化が試みられてきた。


適切な可視化手法は時代によって変わっていく。一方で、ある時代にアルゴリズムの可視化を実装した人が、みな5年後、10年後別の可視化手法への移植をするかというとそうではない。それがなぜなのかはわからない。可視化部分の習得コストが高いからか?


メンテナンスが継続されない問題はどうすれば解決できるか?コードが公開されていなかったり、されていてもライセンスが不明な点が問題の原因ではないか?であれば、GPLで公開すれば、将来の移植版も含めて再利用可能なライセンスであることを保証できるのではないか?


また、アルゴリズムの実装部分と可視化部分は疎結合であるべき。それによって移植性や再利用性が高まる。

適切なサイズ

ついつい機能追加をしてしまいがちだが、実装の読みやすさにも価値があることを考えると、最適なサイズは結構小さい。例えば中置記法のパーサの実装であれば「足し算と掛け算と括弧による優先順位の変更」だけ、とかが適切なサイズだと思う。

これ以上付け加える物が無くなった時でなく、これ以上取り去る物が無くなった時が完成だ - アントワーヌ・ド・サン=テグジュペリ

実装するものリスト

何でもありだと力が分散してしまう。まずは集中するべき。今回は「JavaScriptで実装されていて、インストールなしで、ブラウザ上で動作する」に集中する。

  • 構文木可視化部門
    • A: 構文木SVGcanvasで可視化する部品。汎用のツリー表示ライブラリが使えるかも。
    • シンプルな中置記法のコードをパースして構文木を作る部品。Aと結合して「ブラウザ上で1 * 2 + 3とか書くとリアルタイムで木がにょきにょき変形するのがわかる」というデモが出来る
    • 実用的に使われている言語の、構文木を作る部品とAとを結合させるアダプタ。JavaScriptのブラウザ上で動作するパーサは存在する http://esprima.org/demo/parse.html 後はこれの出力をAに送って可視化するだけ
    • LispのS式のパーサ。最低限数値と加算・乗算だけでよい。これもAに接続できるように
    • Forthのパーサ(って言うほどのものでもないか) Aに接続できるように
  • スタックマシン部門
    • B: 「命令列のどこを実行しているか」と「スタックの状態」をわかりやすく可視化する部品
    • D: Forthの実装 これはほぼスタックマシンの実装と同義。最低限数値と加算・乗算だけでよい。Bと結合して可視化されること
    • スタックマシンを使っている言語のバイトコードを実行 たとえばPythonであれば文字列として受け取ったソースコードバイトコードコンパイルして返すHTTPサーバを書くことができるから、Pythonバイトコードを実行するJSを書けばブラウザ上でステップ実行できる。Bと結合して可視化されること
    • Lispパーサの出力をForthにコンパイルしてDで動かす
  • 構文木書換え部門
    • C: 構文木を部分的に書き換えていくことで計算を行う。Aと結合して可視化されること
    • Lispのパーサからの出力をCにつないで実行
    • Lazy K実装。Aと結合して実行過程が可視化される。
  • 機械語部門
    • EDSACシミュレータ。シンプルな機械で機械語を学ぶために。ただし命令の読みにくさを保存する必要性はないのでわかりやすいエイリアスをつける。
    • Brainf*ck: ただし読みにくさを保存する必要はないので、わかりやすいエイリアスをつける、数値をstoreする命令を足す、などを行う。
    • 将来的には上記の機能限定されたForthやLispから機械語へのコンパイラを実装する。コンパイル過程を可視化する。