Rubyist のための他言語探訪 【第 8 回】 Forth

著者:まつもとゆきひろ

はじめに

本連載で取り扱う言語の選択にはいつも気を使います。

世の中にはそれこそ星の数だけプログラミング言語があるので、珍しい言語というだけなら枚挙にいとまはないのですが、とはいえ、単に珍しい言語を紹介するだけでは蘊蓄以外にあまり役に立たないので、以下のような条件を満たすような言語を選ぼうと思っています。

  • 誰もが知っているような言語ではない
  • 有名ではなくてもある程度の実績がある
  • (上記の結果として) 誕生してからある程度時間がたっている
  • 他の言語には見られない珍しい特徴がある

言語が数多くあるといっても、これらをすべて満たす言語はなかなか見つからないのが実情です。皆さんもなにか「これ」という言語を思いついたら教えてくださいね。

今月も苦労して考えついた Forth について紹介します。

Forthについて

Forth は、アメリカ国立電波天文台の Charles H. Moore によって開発された、一風変わった表現を持つプログラミング言語です。 元々は 1970 年代初頭に天文台の機器制御のために開発されたということです。

Forth の名は Moore がこの言語を機械語、アセンブラ、コンパイル型言語に続く、「第 4 世代言語」と見なしていたことに由来します。 本当は 4 番目だから fourth とつけるつもりでだったのに、当時 Moore が利用していたミニコンのファイル文字数制限が 5 文字だったため Forth になったということです。

特徴としては、とにかく言語仕様が小さく、処理系がコンパクトなことがあげられます。 元々小さなマシンで開発されたこともありますし、この特徴からいまだに組み込み系で使われることもあるようです。 また、Forth の最大の特徴は「逆ポーランド記法」にあるのですが、それについては次の節で説明します。

(逆) ポーランド記法

Forth のプログラムは逆ポーランド記法 (Reverse Polish Notation - RPN) によって記述されます。

逆ポーランド記法は「後置記法」とも呼ばれ、演算子が式の末尾に登場します。 それに対して関数記法のように演算を指定するものが先頭に登場するものは「前置記法」、二項演算子のように間に登場するものは「中置記法」と呼ばれます。

逆ポーランド記法は 1950 年代半ば頃にオーストラリアの哲学者でありコンピュータ科学者であった Charles Hamblin によって発明されました。 オーストラリア人なのになぜ「ポーランド」かというと、それ以前に元になった「ポーランド記法」が存在していたからです。

「ポーランド記法」は、ポーランドの数学者であるJan Łukasiewiczによって 1820 年に発明されました。 これは要するに、前置記法なのですが、「演算子が要求するオペランドの数があらかじめ分かっていれば括弧が不要になる」という点が斬新でした。 つまり、

 × + 0 1 + 2 3

は、各演算子が 2 引数を取ることが分かっているとかならず

 (× (+ 0 1) (+ 2 3))

と解釈されるということです。 前置記法や中置記法に必要な括弧による曖昧性の除去が不要になるので、表現が非常にコンパクトになります。

「逆ポーランド記法」は、いちばん簡単に表現すると「ポーランド記法」を逆にしたものです。 逆ポーランド記法で表現すると上記の式は以下のようになります。

 0 1 + 2 3 + ×

逆ポーランド記法は (偶然にも) 日本語の語順と相性がよく、上の逆ポーランド式を読み下すと「0 と 1 を足したものと、2 と 3 を足したものを、掛ける」となります。

逆ポーランド記法の解釈にはほとんどの場合、スタックを用います。 スタックを使った意味付けにおいては、

  • リテラルは値をスタックに積む
  • 演算子はスタックから一定数の値を取り出し、結果を積む

という動作をします。ですから、上の式を 1 ステップずつ実行すると、

  • 初期状態 (スタックは空)
  • 0 をスタックに積む (スタック: 0)
  • 1 をスタックに積む (スタック: 1 0)
  • +演算子がスタックからふたつ値を取り、結果 (1) を一つ積む (スタック: 1)
  • 2 をスタックに積む (スタック: 2 1)
  • 3 をスタックに積む (スタック: 3 2 1)
  • +演算子がスタックからふたつ値を取り、結果 (5) を一つ積む (スタック: 5 1)
  • ×演算子がスタックからふたつ値を取り、結果 (5) を一つ積む (スタック: 5)

と動作します。

逆ポーランド記法は、

  • 記法がコンパクト
  • 評価順序に曖昧性がない
  • コンピュータ評価と相性が良い

という非常に優れた記法で、Forth のパワーの多くはこの記法によっています。 逆ポーランド記法は Forth 以外にも、古いタイプの HP 関数電卓でも採用されています。

ワードとディクショナリ

Forth のあらゆるプログラムは「ワード」の並びです。 Forth の「ワード」は他の言語における「手続き」や「演算子」またはリテラルなどに相当します。

新しいワードを定義するには「:」ワードを用います。

 : DOUBLE ( n -- 2*n ) 2 * ;

「:」から「;」までがワードの定義になります。: の直後にあるのが定義するワードの名前です。 ここでは「DOUBLE」になります。 括弧から対応する括弧まではコメントになります。 ワード定義の後ろには、「–」ではさんで入力時と出力時のスタックの状態を示すのが一般的のようです。

ごく簡単なものを除いて、Forth のプログラムは「ワード」を定義することで行います。 プログラムは「ワード」の集まりですから、「ディクショナリ」と呼びます。

制御構造

逆ポーランド記法を活用する Forth では、制御構造もやや特殊です。 Forth の if 文は以下のような形式になります。

 cond IF true-part ELSE false-part THEN

IF ワードは、スタックトップが真であれば IF と ELSE の間のワード列を実行し、偽であれば ELSE と THEN の間を実行します。 C の三項演算子 (cond ? true_part : else_part) にちょっと似ているかもしれません。

ループも同様です。

 BEGIN word... UNTIL

これは BEGIN から UNTIL の間までを繰り返します。 UNTIL を実行した時点でスタックトップが偽であれば、BEGIN の位置までジャンプします。 真であれば、UNTIL の次を実行します。

Forth にはもうひとつ、DO ループもあります。

 end start DO word... LOOP

start から end までの回数 DO と LOOP の間のワードを繰り返します。

変数

基本的にスタックを使って値の受渡をする Forth では変数の必要性は他の言語よりも少ないのですが、それでも変数を全く使わないというのは難しいときもあります。 そのようなときのために Forth にも変数があります。 Forth の変数は VARIABLE ワードで定義します。

 VARIABLE var
 123 var !	(varに123を代入)
 var @		(varの値123をスタックトップに)

これによって var というワードが定義されます。 そのワードを評価すると、その変数に割り当てられた「アドレス」(整数値) をスタックに積みます。

変数への代入は ! ワードを使います。! ワードはスタックトップにあるアドレスに次のスタックの値を格納します。

変数の値を取り出すためには @ ワードを使います。 @ ワードはスタックトップのアドレスに格納されている値をスタックトップに積みます。

Forth の仲間たち

Forth は単純ながら柔軟性が高く、一部の人に非常に高い人気があり、あまり目立たないところで活躍しています。 たとえば、Sun や Apple のマシンの Boot ファームウェアである OpenFirmware には Forth が組み込まれています。 FreeBSD のブートローダにも Forth 系言語 FICL が組み込まれています。

また、 Forth の柔軟性の魅力は、Forth の基本的なアイディアを踏襲した言語を数多く生んでいます。 たとえば、プリンタ用ページ記述言語の代表格 (というより、他のページ記述言語をすでに駆逐してしまった) Postscript は逆ポーランド記法を用いた言語です。 おそらく世界でもっともたくさん使われている後置記法言語ですが、世界で一番人間の目に触れる割合の少ない言語でもあります。

すでに述べたように逆ポーランド記法は日本語の語順によく似ています。 そのことから、Forth に良く似た文法を採用した日本語プログラミング言語 Mind が誕生しました。

 4と 5を 加え 表示する。

というような外見になります。

それから、逆ポーランド記法と関連の深いスタック方式は仮想マシンの実装に広く使われていて、JVM や YARV などで採用されています。

まとめ

今回は広くいろいろなところで活躍していながら、全然目立っていない言語である Forth を紹介しました。 Forth はコンパクトで実装も簡単でありながら、高性能の処理系があることでも有名です。 言語処理系の実装に興味のある人なら一度は調べてみて損はないでしょう。

Forth についての情報は以下から入手することができます。

日本語プログラミング言語 Mind についての情報は以下から入手することができます。

次回予告

未定です。リクエスト歓迎。

著者について

matz_in_suit.jpgまつもとゆきひろは自他ともに認める日本を代表する言語オタクです。 言語好きが昂じて自分の言語を設計してしまった大馬鹿者です。 が、オタクとかハッカーとか呼ばれる人種はみんな多かれ少なかれそんなものじゃないでしょうか。

バックナンバー