Smalltalk-アハ-体験
Uncle BobがAlan Kayの原義寄りのオブジェクト指向プログラミングの定義をバスローブ姿で述べるポストをしていて、それへのレスポンスを眺めたり、突っ込みを入れたりするうちに(たぶん^^;)完全に言語化できました!
----
Smalltalkは主に効率化のために当初(Smalltalk-72)の真のメッセージング機構(古いLispのFEXPRに着想を得た設計。なお、ハードウエア性能の制約で非同期化は断念)を捨て、単なるメンバー関数コールに縮退してしまいました。その結果、一見すると他のOOPLとの区別、特に「メッセージング」の本質的価値がわかりにくくなってしまいました。しかし、この縮退にもかかわらず、Smalltalkには他の一般的なOOPLでは得にくいユーザー体験があります。それが何かを言語化してみました。
実は、Smalltalk-76以降のSmalltalkでは、Smalltalk-72時代の「真のメッセージングのプログラミング」の実践から得られた主に3つの“ならでは”の特徴が、単なるメンバー関数の動的コールの枠組みの中でも不完全ながらも実現可能な形で巧妙に「偽装」され「疑似体験」できるように仕組まれています。(Alan Kayはこの工夫を「Dan Ingallsのマジック」と呼んでいます。)
1. 構文の自由度
一般的なOOPL: 固定された構文規則に従う必要がある
Smalltalk-72: トークン列で表現されたメッセージを受け取るため構文と呼べるものはほぼ無い→自由
以降のSmalltalk: キーワードメッセージ式でメソッド名(セレクタ)をキーワードに分割することでトークン列を再現+doesNotUnderstand: メソッドオーバーライドで「存在しないメソッドのコール」、つまり、自由なメッセージ送信を偽装
(参考) Ruby: 引数を囲む括弧の省略、プライベートコールでの self の省略という別アプローチ+method_missing
次項の「ブロック呼出しメソッド」との組み合わせで、DSL(ドメイン固有言語)の構築が驚くほど容易になります。
2. 引数評価のタイミング制御
一般的なOOPL: 引数は関数呼び出し前に必ず評価される
Smalltalk-72: メッセージとして送られたトークン列は、レシーバーの判断で自由なタイミングで評価
以降のSmalltalk: ブロック(記法が簡易なラムダ式、あるいはクロージャ)を引数に取る高階関数コールで偽装
(参考) Ruby: ブロック付きメソッド呼出し構文で同様の効果
一般的な値呼び(call‑by‑value)の関数だけでは、引数は必ずコール前に評価されるため制御構造などが作れません(特殊形式やマクロ、類似の言語機能が追加で必要)。古いLispのFEXPR(評価抑止関数)に着想を得た設計をベースにした Smalltalk-72 のメッセージング(トークン列をそのまま引数として、特殊な関数のように見立てたオブジェクトに渡す)では、制御構造などの言語機能の拡張が驚くほど容易でした。ブロック付きメソッド呼び出しは、FEXPRやSmalltalk-72のメッセージング、ましてマクロほどの自由度はありませんが限定的にこれをシミュレートします。(前項とも連携)
3. 動的性、特にメタレベルの柔軟性
一般的なOOPL: メタプログラミングは限定的か複雑
(参考) Lisp: 式自体がアトム、もしくはリストであり(評価時は S式として評価)、まったく自由
Smalltalk-72: 式自体が単なるトークン列であり(評価時は、最初のトークンがアクティベートされることで続くトークン列をメッセージとして受け取る機構)、まったく自由
その後のSmalltalk: 処理系に絡むモノ・事象も全てオブジェクトで、特に実行コンテキストがファーストクラスであり、擬変数(数少ない予約語のひとつでもある)の thisContext でいつでもアクセス可能
実行中のコードの内部状態を検査・変更できるため、デバッガやプロファイラといった高度なツールを言語自身で実装することが驚くほど容易になります。
近年は多くの処理系がイントロスペクションや動的コード生成を備えていますが、実行中のスタックフレームを自在に改変してそのまま処理を再開できる――すなわち、高機能デバッガの心臓部を単独で構成し得るレベルの動的介入 (intercession) をフルスケールで公開している例は、安全性重視の流れもあり今なお極めて稀です。
アハ体験
これらの特徴ひとつひとつでも十分なユーザー体験を得られますが、さらに統合された環境の中でそれらがシームレスに連携するシナジー効果は非常に強く、プログラミング体験やプログラミング言語(ひいてはソフトウエア全般、もっというとパーソナル・コンピューター)に対する固定観念を大きく拡張します。この、ある種の開放感は、Smalltalkによく似た機能を持ったRubyや、旧IBM VisualAge for JavaなどのSmalltalkベースの環境を通じて間接的に出会ったとしても、プログラマの思考に永続的な影響を与えるでしょう。
NotebookLMによる音声概要:https://youtu.be/LVP0zr4ryIc?si=mUSkYitsOpGEKqH_