1. 命名と粒度はForth設計の中核である
Thinking Forth の重要な主張の一つは次である。
「コードの質は、ワードの粒度と名前の質で決まる。」
Forthは語彙中心であり、語彙の善し悪しがプログラム全体の読みやすさ・保守性・拡張性を左右する。
したがって、良いワードの粒度・名前のつけ方を早期に習得することは、講座全体を通じて極めて重要である。
2. なぜワードの粒度が重要なのか
Forthは“短い語彙を積み重ねる”言語
C言語のように一つの関数を長く書くのではなく、Forthは
- 一つの操作に一つのワード
- 書きながら細かく分割
- 後で統合して意味のある文章を作る
というスタイルが最適である。
: PROCESS-LINE PARSE-NUM COMPUTE-RESULT PRINT-RESULT ;
このように“自然な文章”になることが理想である。
3. ワードの粒度を判断する基準
ワードは「一つの責任」であるべき
「値を読む」「値を変換する」「値を出力する」を一つのワードに閉じ込めてはいけない。
: DO-ALL ( -- )
READ-LINE >NUMBER . ;
: READ-VALUE ( -- n ) READ-LINE >NUMBER ;
: PRINT-VALUE ( n -- ) . ;
スタック操作が複雑なら分割する
次のようなワードは危険である。
- SWAP, ROT, OVER が多い
- スタック効果
( ... -- ... )が長い - 実装を見ないと何を返すか分からない
: BAD ( a b c -- d )
ROT + SWAP * ;
: SUM-OF-FIRST-TWO ( a b c -- c sum )
SWAP OVER + ;
: MULTIPLY-REMAINDER ( c sum -- d )
* ;
ただし、Forthは短い語彙をつないで「文章を作る言語」である。分割しすぎると読みにくい場合は、再統合してよい。
ワードが長くなったら必ず分割を検討する
- 10行を超える
- 3つ以上の構造ブロック(IF、DOなど)がある
- スタック効果が2行以上になる
このような場合は、新しい語彙を作って構造を語彙に押し込むべきである。
REPLで直接テストできること
Thinking Forth の哲学とは、
テストできないワードは設計が悪い。
10 FOO . のように、ワード単体で確認できる構造が理想である。
大きいワードは必ず、分割した小さなワードの組み合わせで構成すべきだ。
4. ワード命名の原則
名前は「意味」を伝えなければならない
ワード名の意味が曖昧だと、全体の可読性が損なわれる。
NGな名前の例
DOITCALC1TMP-
XX,YY
これらの問題点
- 意味が伝わらない
- 役割が不明
- 他のワードと混同しやすい
問題領域の言葉を使う
Forth的思考では、コンピュータの操作名ではなく、問題そのものの言葉を使うことが理想である。
例:伝票計算の場合
: SUM-LINES
: ADD-INVOICE-AMOUNT
「動詞+名詞」がForthの理想的な語彙
Thinking Forth でも特に推奨される命名形式である。
- READ-FILE
- COMPUTE-TOTAL
- PARSE-RECORD
- UPDATE-SCORE
- WRITE-CSV
その理由は。
- プログラムが“動作主体の文章”として読める
- 処理の中心動詞を明示できる
- 高レベル語彙の設計が容易になる
高レベルのワードほど「意味的」であるべき
次の2つのワードを比較する。
: DO-LOOP-AND-SUM ... ;
: SUMMARIZE-DATA ... ;
高レベルのワードは内部処理を隠す“ラベル”であり、読者に意図を伝えることが最重要である。
5. ワードが“文章になる”設計とは
Thinking Forth は、最終的なプログラムが「文章のように読めるべきだ」と主張する。
LOAD-FILE
PARSE-RECORDS
SUMMARIZE-DATA
WRITE-REPORT
これらが順に並ぶと、Forthを知らない人でも“何をしたいのか”理解できる。
この読みやすさこそ、ワード粒度・命名規則の最終的な目標である。
6. 実例:命名と粒度の改善プロセス
以下の“悪い例”を Thinking Forth の視点で改善する。
: DO-ALL ( -- )
BEGIN
READ-LINE DUP 0= IF DROP EXIT THEN
>NUMBER +
AGAIN ;
問題点:
- 名前が抽象的
- 複数責任
- スタック操作が不透明
- ワードの意図が読み取れない
: READ-VALUE ( -- n|0 ) READ-LINE DUP 0= IF EXIT THEN >NUMBER ;
: ADD-VALUE ( n -- ) + ;
: READ-SUM ( -- total ) 0 BEGIN READ-VALUE DUP WHILE ADD-VALUE REPEAT DROP ;
改善点:
- 語彙が意味を持つ
- 小さな単位でテスト可能
- プログラムの意図が文章として現れる
- 側方効果が小さい
- ワードは短く・単機能で
- スタック操作が複雑なら必ず分割
- 名前は“問題領域の言葉”でつける
- 動詞+名詞が基本パターン
- 高レベル語彙ほど意味的であるべき
- 語彙の連なりが文章として読める設計が理想
- REPLで直接テストできる粒度が最適