データフロー型のプログラミング言語を作ってみる

公開2011-09-07
更新2011-09-21

はじめに

 最近はプログラミング言語、それ自体への興味も強くなっています。

 自分で一からプログラミング言語・ツールを作ってみる、考えてみる、というのも興味深い研究対象ではあります。実際に手を出すかどうか、あるいは実用になるものができるかどうかは、さておいて。

 以前から「作ってみたい」があったので、試作を始めてみました。どこまで実現できるかは分かりませんが、制作過程の記録、理解できたこと、気付いたことなどを、学習ノートとしてまとめてみます。

どんな言語?

 データフロー型(および、それに関連する関数型やリアクティブ)に興味があります。一般的な手続き型と比べて、より「宣言的な記述」であること、ビジュアル化やマルチスレッドとの相性が良さそうなところにも惹かれます。

*

目標と実装言語

 スタンドアローンの実行環境、もしくは C/C++ からライブラリーとして利用できる、GUI とマルチスレッドも扱える、静的型付けの言語・プログラミングツールを目指します。(目標は高いですね!)

 当面の実行環境は、Windows XP 以降で動作するインタープリターになります。実装言語は C99 です。

 筆者は .NET Framework と C# に慣れていますが、折角なので、ここは「ランタイム不要で動く」(本体は OS 非依存)をやりたいですよね。C でごりごりと書くのが、意外と楽しいようです。

C99

 C++ ではなくて C99 で書いています。

 プログラミング言語の仮想機械の実装は、割と C で書かれることが多い印象があります。できるだけポータブルにしたいから、というのが、そのもっともらしい理由でしょうか?

 また、言語の仕様がコンパクトであるところを好む(複雑な C++ は嫌う)向きもあるようです。(あるようです、というか、私もそうです。)流石に「アプリケーション」を C だけで書くのは大変ですが、「言語の仮想機械」であれば、なんとかなりそうな気配がするのです。

 もう一つ、Tiny C Compiler という C 言語コンパイラーの、コンパイル速度が“超絶に”速くて気に入りました。-run オプションを付けると、.exe を出力することなく、まるでスクリプティング言語であるかのように実行できます。

 MinGW の GCC 4.5.2 でもビルドを確認するようにしています。TCC は速いのだけど、エラーを素通りするところがあるので、区切りが付いたら GCC で警告の有無を確認しましょう。

 Visual C++ は……まだ試していません。

どこまでできたの?

2011-09-21 … インタープリターの実装中です。実用的なツールには至っていません。

 ウィンドウを出して絵を描ける程度まで実装を進められたら、α版として公開する予定です。

できたこと

2011-09-07

 現在はマルチスレッド化に取り組んでいます。GUI を扱えるようになりたいので、実行環境のメインループとウィンドウのメッセージループを同時に動かせることが、最低限の要求になります。それでなくとも、マルチスレッド対応は後付けではなくて、最初から実装しているべきもののように思われます。

2011-09-14

「ノードの非同期的な実行」ができるようになりました。ノード単位でスレッドの名前を付けることができます。(タスクとしてサブスレッドに投げられ、非同期に処理される。)メインスレッドとの同期がややこしいです。

「クラス・オブジェクトの生成」と「GC」と「S 式で書かれたソースコードを読み取ってコンパイル、実行する」は、過去に一度、実装してあるのですが、現在の版に統合できていません。これらを統合する作業が残っています。

データフロー?

 データフローのモデルでは、プログラムを「ノードと、その接続」で表します。そのためビジュアルプログラミングの一種として表現されることが多いようです。

 一つのノードは一つの関数に相当します。様々な機能のノードを組み合わせることになりますが、しかしノードの大分類は3種類、「入力」と「加工」と「出力」だけです。どのノードも、この分類で説明されます。

*

 データフローでは、「あらゆるプログラムは『入力 → 加工 → 出力』の連鎖である」と仮定してしまいます。普通の、手続き型の言語を「動作の台本を記述する」とするなら、データフロー型の言語は「データの加工工程図を描く」といえます。(「フロー」といっても、「フローチャート」とは、ちょっと違うのです。)

Push と Pull

*

 イベント駆動的な仕組みも、高階関数などの関数的な仕組みも、どちらも欲しい、となると、Push と Pull を組み合わせる形になります。

 このプロジェクトでは、ノードの評価は出力側から Pull で駆動させています。ノードの発火、ノード間のデータの受け渡し手法については Push です。

 逆に Push 型をベースにしたとしても、どのみち高階関数や遅延評価的なものを導入したくなるのでしょう。高階関数とは、つまり評価駆動です。なら最初から Pull 型でいいのでは、と。

参考文献

 既存のグラフィカルでデータフローな汎用プログラミングツールをいくつか挙げてみました。(存在を確認できた、というだけで、どれも詳細までは見ていません……!)

Mindscript
http://mindscript.sourceforge.net/
オープンソース。現在はサイトにアクセスできないようです……。
ビジュアルプログラミング「Mindscript」 … MOONGIFT さんの紹介記事。スクリーンショットがあります。
FlowDesigner
http://flowdesigner.sourceforge.net/
オープンソース。
Marten
http://www.andescotia.com/products/marten/
Mac OS X 専用のプログラミングツール。有償。Prograph CPX という言語が元になっているそうです。
OpenMusic
http://repmus.ircam.fr/openmusic/
音楽編集に特化してはいるが、中身は Common Lisp だそうです。
LabVIEW
http://www.ni.com/labview/
産業・研究者向けの開発環境。ハードウェア制御など。(個人で使うようなものではありません。)

連絡先



Copyright © 2008-2011 Toru TAKAGI