1. Forthは“言語”ではなく“道具箱”である
Forthは、一般的なプログラミング言語と異なり、既存の文法に従って書くものではない。
自分の問題に合わせて語彙(ワード)を作り、言語そのものを拡張しながら解決する
という哲学を持つ。
- Forthとは「問題領域に合わせて構築する言語」である。
- プログラムを書くとは、「必要な語彙を作ること」である。
- 言語仕様より、問題に沿った語彙の体系が中心になる。
この考え方を理解しているかどうかで、Forthプログラミングの質は大きく変わる。
2. Forth的思考の基本:ボトムアップと語彙設計
Forthは“文法ではなく、語彙の追加”で前進する
多くの言語は構文・文法が中心であり、「関数やクラスを書く」ことが目的となる。
一方、Forthでは構文は最低限であり、プログラマ自身が文法的な言葉(ワード)を作り足す。 Forth の主役は構文ではなく“単語(Word)”である。
: SQUARE ( n -- n ) DUP * ;
これは SQUARE という「新しい語彙」を辞書に追加したにすぎない。しかし、これが積み重なると「自分専用の言語体系」ができていく。
ボトムアップ開発:小さな語彙 → 大きな語彙へ
「Forthシステムは、ツールを積み上げて拡張する“積層的な世界”である」
そのため、大規模な仕様を最初から固定するのではなく、次の流れで設計を進めるのが理想である。
- まず小さな語彙(低レベル操作)を作る
- REPL で試す
- 必要な語彙を追加しながら高レベル構造を育てる
- プログラム全体が“意味のある文章”になる
例:長さ合計を計算するプログラムを作る場合
いきなり全体を作るのではなく、まず「必要そうな語彙」を下から順に作る。
: READ-LINE ... ;
: PARSE-NUM ... ;
: ADD-SUM ... ;
そして最後に
: SUM-FILE ( -- total )
OPEN-FILE
BEGIN READ-LINE WHILE PARSE-NUM ADD-SUM REPEAT
CLOSE-FILE ;
という“文章”を構成する。
Thinking Forth が繰り返すキーワードは evolve(進化させよ) であり、設計は“育てる”ものである。
3. スタックの流れ(データフロー)を第一に考える
Forthの制御構造より重要なのは「データの流れ」
Forthでは IF や DO LOOP などの制御構造は最低限である。むしろ重要なのは、データがスタック上でどのように移動するかである。
- スタックの状態を“常に予測”しながら書く
- ワード定義の冒頭に スタック効果注記
( x y -- z )を書く - スタック操作が複雑なら、ワードを分割して単純化する
スタックはデータ構造ではなく「会話の流れ」
Forthにおけるスタックは単なるデータ構造ではなく、ワード同士が情報を受け渡す会話のようなものである。
- 上位ワードは下位ワードがスタックへ置く値を信頼する
- 下位ワードは「この値だけ返せばよい」とシンプルに振る舞う
実例:距離を平方根で求める
: DIST ( x y -- r )
DUP * SWAP DUP * + FSQRT ;
スタック効果を理解していれば、
上記が「x^2 + y^2 の平方根」と自然に読める。
4. 言語を“作る”とはどういうことか:辞書と抽象化
Forthは辞書中心の世界
Forthシステムの内部は“辞書”で成り立っている。
- 辞書とは、ワード名とその動作の組である
- ワードを定義することは、辞書に新しい語彙を追加すること
- プログラムが大きくなると、「自分専用のミニ言語」ができる
この仕組みを “Language Growth(言語の成長)” と呼ぶ。
抽象化は「名前を与える」ことから始まる
抽象化とは、複雑な操作に名前をつけ、その名前の裏側で低レベル操作を隠すことにほかならない。
: >CM ( x y z -- c ) ... ;
のような抽象的なワード名は意味不明である。
しかし
: COMPUTE-MEASURE ...
なら、読むだけで意図が分かる。
抽象化の中心は名前である。
名前が悪ければ設計は悪くなる。
5. REPL を最大限に活用する
推測せず、試す
Forthの対話環境こそ、Thinking Forth の実践に最適である。
- ワードを作る
- 即座に試す
- 改良する
- また試す
この繰り返しにより、自然に問題に合った語彙体系が育っていく。
2 SQUARE .
10 20 DIST F.
この一行の実験が、プログラムの信頼性を劇的に向上させる。
テストしづらいワードは設計が悪い
テスト不可能なワードを設計してはならない