stanford-oval/wikipedia huggingface dataset:
Smalltalk
概要 > Smalltalkの変遷

※この節はを元に執筆されている。
| 名称 | 備考 |
| --- | --- |
Smalltalk-71: 最初にSmalltalkの名前を冠した言語だが、文法など一部仕様が定められただけで実装はされていない。
Smalltalk-72: メッセージングの機構により最初に動作したSmalltalk。初期のGUIはタートルグラフィックスで表現されたウインドウやメニューなど原始的な構成で、言語仕様的にもクラスが関数であったり、メソッド定義がリーダーマクロ（あるいは簡易パーサー記述）のようであったりと、現在のSmalltalkとは異なる点が多い。
Smalltalk-74: Smalltalk-72に対し、処理系の高速化、GUIの整備、オブジェクト指向仮想メモリ (OOZE) を導入したバージョン。
Smalltalk-76: 現在のメッセージ式に近い文法（特にキーワードメッセージ式）を取り入れたSmalltalk。メタクラス、第一級オブジェクトとしてのブロックなどはまだない。
Smalltalk-78: Smalltalk-76を、可搬式の試作機「NoteTaker」で動作するよう8086向けにBitBlt等を再構築し、小さく整理したバージョン。
Smalltalk-80: 現在に知られる仕様となったSmalltalk。
ObjectWorks: Smalltalk-80を一般に普及させるために開発・販売されたSmalltalk。
VisualWorks: ObjectWorksを引き継ぎ開発されたSmalltalk。Smalltak直系の子孫で現代に至るSmalltalkの中で本家と言える存在である。
Apple Smalltalk: Smalltalk-80 v1（リリース前バージョン）を元に、XEROX社に許諾および指導を受けてAppleが開発したSmalltalk。同時期にDEC、テクトロニクス、ヒューレット・パッカードでも同様の試みがなされている。
Squeak: Appleに移籍したアラン・ケイ、ダン・インガルスらによってApple Smalltalkを元に開発された。Smalltalkの設計者により開発されており、いわば分家と言える存在である。
Pharo: Squeakから派生した実装。大胆で実験的な機能追加の試みが多いが、2017年現在精力的かつ活発に開発が進められているSmalltalk処理系のひとつ。
概要 > Smalltalk とオブジェクト指向

豊富で整備されたクラスライブラリーは、特にオブジェクト指向プログラミングの手本とされ、デザインパターンの宝庫と称されるまで洗練されたものになっている。また、後世の多くのオブジェクト指向プログラミング言語に直接間接的に多大な影響を与えた。
アラン・ケイが「オブジェクト指向」という言葉を創った当初は、Smalltalk システムが体現した「パーソナルコンピューティングに関わる全てを『オブジェクト』とそれらの間で交わされる『メッセージ送信』によって表現すること」を意味していた。しかしのちに、C++ の設計者として知られるビャーネ・ストロヴストルップが（自身、Smalltalk の影響は受けていないと主張する）C++ の設計を通じて整理し発表した「『継承』機構と『多態性』を付加した『抽象データ型』のスーパーセット」という考え方として広く認知されるようになった（カプセル化、継承、多態性）。現在は、両者の渾然一体化した曖昧な概念として語られることが多い。
概要 > Smalltalk の独自性

Smalltalk は、オブジェクトへのメッセージ送信を率直に記述する表記の特殊性や、制御構造をもたずオブジェクトへのメッセージ送信の形で記述する徹底ぶりとも併せて、C言語や C++ などの流れを強く受け継ぐ言語、およびその開発手法に慣れた開発者にとって極めてとっつきにくい言語・環境であるといわれている。このことは、Smalltalk が単なるプログラミング言語ではなく、従来のオペレーティングシステムの概念をも包括する「環境」であることが一つの理由である。Smalltalk を単なる言語としてとらえると、他の言語と比較したとき、使用するオペレーティングシステムのグラフィカルユーザインターフェースに全く従わないなど、その独自性が大きな「欠点」として映る場合もある。
これは VisualWorks や Squeak（） など、旧来の Smalltalk 環境、つまりダイナブックコンピュータ環境の要素を引き継ぐ統合開発環境を通じて Smalltalk 言語や処理系を学ぶなら、多かれ少なかれ新たなオペレーティングシステムに接するような心構えを持つべきことを意味する。
環境および処理系としてのSmalltalk > Smalltalk 環境から見たSmalltalk 言語

Smalltalk 環境から見た Smalltalk 言語は、いわば bash などのシェルに近い。Smalltalk 環境内であればどこでもマウスで選択した文字列を Smalltalk のソースコードとして実行できるためシェルにコマンドを打ち込んだ時の様に簡単な問い合わせをすぐ実行できるようになっている。
例えばオブジェクト(クラスやメソッドも含む)の構造を調べたければ、そのオブジェクトに#browse（）セレクターあるいは#inspect（）セレクターを使ったメッセージ式を書き、そのメッセージ式をマウスで選択してdo it(WindowsであればCtrl+Dを押す)すれば良い。
また、設定値の指定に Smalltalk 言語のメッセージ式が使われる。現在設定されている値がメッセージ式として取得でき、値の設定をメッセージ式として指定する。この設定値を指定するメッセージ式は Smalltalk 環境の実行中に設定用のウィンドウから入力される。
環境および処理系としてのSmalltalk > 仮想機械方式 > 仮想機械による実行

Smalltalk 環境は、Smalltalk 環境の実行方法として現実のハードウェアに依存している機械語命令を使わず、現実のハードウェアから独立した中間言語命令(仮想機械に対する機械語命令)を仮想機械により実行する仮想機械方式を採用している。 Smalltalk の中間言語命令は、全てイメージファイルというファイルに書き込まれ Smalltalk の仮想機械はそのイメージファイルを読み込んでSmalltalk 環境を実行する。
この仮想機械方式による Smalltalk の実行方法は Smalltalk の言語仕様にも含まれている。
なお、Smalltalk が導入したこの仮想機械方式はEULERのpコードマシンからアラン・ケイが着想を得たものである。
環境および処理系としてのSmalltalk > 仮想機械方式 > イメージファイル

イメージファイルは、Smalltalk 環境の実行状態をそのまま保存したファイルである。イメージファイルは Smalltalk 環境実行中に生成された全てのオブジェクトを直列化して保存することでSmalltalk 環境の実行状態を保存している。この直列化されたオブジェクトには、Smalltalk の中間言語も含まれている。イメージファイルに含まれる中間言語命令は、Smalltalk 自身によって記述されたコンパイラーによってソースコードから翻訳された、バイト列のオブジェクトである。
環境および処理系としてのSmalltalk > 仮想機械方式 > 仮想機械とブートストラップ

Smalltalk の実行環境が全く存在しない初期の状況ではコンパイラーも仮想機械も Smalltalk で用意する事はできない。このため Smalltalk の初期段階ではALTOのアセンブリ言語によりコンパイラーや仮想機械が実装されていた。
環境および処理系としてのSmalltalk > 実行時書き換え

Smalltalk環境は翻訳方式を使う処理系としては珍しくプログラムの実行時書き換えを基本とする。例えば後述のClass Browserに入力したプログラムはソースコードを中間言語に変換したあとSmalltalk環境の一部として取り込まれ、環境を再起動したり読み込み操作をしなくても起動中のSmalltalk環境内で実行することができる。C++のような翻訳式の言語であれば原則、ソースコードを書き換えた場合は原則プログラムの再起動が必要となる。またPythonの様な言語ではソースコードを再読み込みする処理を予め書き換えたい処理の呼び出し元に組み込んでおかなければソースコードをいくら書き換えても動作に反映できない。Smalltalkではその再起動や再読み込み処理の組み込みが必要ない。このため環境をソースコードを書き換える都度環境全体を再起動しなくて済むのはもちろん、Windowを表示するプログラムを作った場合であれば、Window内のButtonの動作を変更する時もWindowを表示したままソースコードを書き換えて動作を変更できる。このためButtonを押すまでに複数の手順が必要なプログラムやWindowの表示に時間がかかるプログラムでもButtonを表示した状態から再起動せず何度でもやり直しができ効率的なソースコード変更が可能になっている。
環境および処理系としてのSmalltalk > 環境の種類

| 環境 | 使用している仮想機械 | 有償版 | 無償版 | CPU | OS | 備考 |
| --- | --- | --- | --- | --- | --- | --- |
| ObjectWorks | - | ○ | ○ | - | Win | 2017年現在VisualWorksを販売するCincomのWindows向け製品となっている。 |
| VisualWorks | Object Engine | ○ | ○ | x86/x64 | Unix/Linux/OSX/Win | ゼロックス時代のSmalltalkを引き継ぐSmalltalk環境。名前空間やイメージファイルからモジュールを切り離せるパーセル、OSのデスクトップ上に表示できるウィンドウ等以前のSmalltalkより大きく拡張されている。2017年現在も活発に開発されている。 |
| Squeak | Cog VM | × | ○ | x86 | Unix/Linux/OSX/Win | Apple Smalltalkから派生したプラットフォーム非依存やマルチメディア対応を強化したSmalltalk環境。 |
| Pharo | Cog VM | × | ○ | x86/x64/Arm | Unix/Linux/OSX/Win/MacOS | Squeakから開発向けに派生したSmalltalk環境。 |
| GemStone/S | - | ○ | ○ | x86/x64 | Unix/Linux/OSX/Win | データベース管理システムとしての用途に特化したSmalltalk環境。その用途からGUIは無い。2017年現在GemTalk systemにて無償版が配布されている。2017年現在も活発に開発されている。 |
| GNU Smalltalk | - | × | ○ | x86/x64/arm | Unix/Linux/Android/OSX/Win | GUI無しでの開発に特化しており他の環境ではGUIを前提としている機能をCUIで実行できる。ただしGUI環境も用意されている。Cと連携するための機能が他の処理系と比較して特に強力であり、関数のポインターを指定すべき引数にブロックを渡したり、関数呼出もできる各種ポインター操作ができるようになっている。しかも、関数のポインターとして渡すブロックは変数を束縛した状態で渡す事が可能になっている。 |
| Strongtalk | - | × | ○ | - | Win | 言語仕様に静的型検査を追加したSmalltak環境。Hot spotによる最適化を初めて実装したVMで極めて高速に動作する。Strongtalkで開発されたHot spot技術はJavaVMなどにも移植された |
| Gradualtalk | Cog VM | × | ○ | x64 | Unix/Linux/OSX/Win | Pharoの環境を元に言語仕様に静的型検査と動的型検査を追加したSmalltak環境。 |
| Amber Smalltalk | - | × | ○ | Web Browserに依存 | Web Browserに依存 | Web Browser上で動作するSmalltalk環境。 |
| Dolphin Smalltalk | - | - | - | - | Win | Windowsに特化しておりOS固有の機能やOS固有のGUIを使用できる。OSとの親和性が高い。SmalltalkからJavaを呼び出すJNIPortを最初に実装した処理系であり、JNIPortが使える処理系ではDolphin Smalltalkの名前を目にする機会が多い。 |
| Smalltalk/JVM | - | - | - | Java VMに依存 | Java VMに依存 | Java VMを使用する。 |
| #Smalltalk | - | - | - | 共通言語基盤に依存 | 共通言語基盤に依存 | .NET Frameworkを使用する。 |
| Smalltalk/X | - | - | - | - | Unix | Unixで動作するSmalltalk環境。 |
| Smalltalk/V | - | - | - | - | - | pc98で動作するSmalltalk環境。 |
| VisualAge | - | - | - | - | - | Smalltalk/VからIBMが派生させて開発したSmalltalkベースの統合開発環境。Javaで記述されたEclipseの原型でもある。 |
| VA Smalltalk | - | - | - | - | - | IBMが開発を停止したVisualAgeの派生製品。2018年現在も開発が継続されている。 |
| Smalltalk MT | - | - | - | - | Win | Windowsに特化しActive Xを生成できる。 |
| Little Smalltalk | - | - | - | - | - | Smalltalk環境として稼働する上で必要最低限の機能だけを備えるSmalltalk環境。 |
SmallScript（S#）: -
Ambrai Smalltalk: -
| ConcurrentSmalltalk | - | - | - | - | - | アクターモデルによる分散処理を導入した環境。 |
Distributed Smalltalk: -
PIC/Smalltalk: -
Smalltalk Express: -
| ParcPlac Systems社 Smalltalk-80 V2.5 | - | - | - | 80386SX以上 | - | pc98で動作するSmalltalk環境。動作環境として、CPU 80386SX以上、メモリ3.6Mbyte(V2.5Jでは4.6Mbyte)以上搭載、ハードディスク空き容量5Mbyte(同10Mbyte)以上とされるが、当時のマシン環境としてPC-9801DA21に7.6Mbyte以上のメモリと80Mbyte以上のハードディスクを装備した環境を推奨。 |
環境および処理系としてのSmalltalk > GUIツール > 準標準的なGUIツール

GUIを使わないような特殊なものを除き、大半のSmalltalk環境では次のようなGUIツールが用意されている。
Class Browser(System Browser)
Transcript
Workspace
Debugger/Notifier
Inspector
Smalltalkの開発ではこれらのツールを使って開発する事が半ば前提となっている。
環境および処理系としてのSmalltalk > GUIツール > Class Browser(System Browser)

Smalltalk環境内に存在する全てのクラスを(存在する場合は名前空間も)表示/編集できるツールで、Smalltalk開発において中核となるツールである。
環境および処理系としてのSmalltalk > GUIツール > Transcript

言うなれば出力しかできないコンソールといったツールで、プログラムの実行結果を簡易的に表示したいときに使われるツールである。Smalltalk環境内でTranscript変数に書き込まれたメッセージは、全てこのTranscriptに表示される。
環境および処理系としてのSmalltalk > GUIツール > Workspace

言うなればコンソールの入力側とテキストエディターを組み合わせた様なツールである。一見すれば書いたコードを実行できるだけの簡易的なテキストエディターにしか見えないが、WorkspaceはWorkspace変数というWorkspace固有の変数を持っており、Workspace内で実行されたSmalltalkコードの実行結果を保持することができる。このため、長いコードを書くような用途では使わず、Smalltalk環境に対するパッケージの追加や、環境設定、ファイルの一時的な操作など一時的な操作を実行する場所として使われる。
環境および処理系としてのSmalltalk > GUIツール > Inspector

オブジェクトの内部構造を再帰的に表示するツールである。また、多くの場合オブジェクトの編集が可能でありWorkspaceと組み合わせてオブジェクトを組み立てていくことが可能である。例えば画面部品をWindowを表すオブジェクトに組み込み、クラス変数に格納するといった具合である。Inspectorに限らずSmalltalk環境全体に共通することであるが、オブジェクト内の変数を表示するときは内部構造そのままではなくオブジェクトの文字列表現で表示する。このため内部がHash map等複雑な構造になっている場合でもDictionary (#key -> 'value' )といった読み易い表示となる。
言語としてのSmalltalk > 言語としての設計思想

言語として Smalltalk が目指したもの。それは計算機を計算機の集合体として構築し、さらに計算機を構成する個々の計算機も計算機の集合体で構築するというように、再帰的な計算機を構築することであった。この再帰的な計算機を構築している無数の計算機は、個々の内部には干渉せずメッセージによる通信のみによって相互作用を発生させ目的の計算を完遂させる。
ここでいう計算機が Smalltalk ではオブジェクトという形で実装された。
この設計思想の誕生は、ロバート・S・バートン（英語版）とB5000の設計者らが会談した際の次の発言をアラン・ケイが聞き「計算機の全体を計算機とみなした場合、その計算機の構成要素を計算機に分解するのではなく関数やデータ構造に分解したいと誰が思うのか」と疑問を浮かべた事がきっかけとなっている。
「再帰設計の基本原理は、部品が全体と同じ力を持つようにすることだ」
ここで言及された再帰という概念は、オブジェクトの成立以外にも Smalltalk の至るところに影響を与えている。
反復はメソッドの再帰呼び出し。
インスタンスオブジェクトを生成しているクラスオブジェクトも、クラスオブジェクトに所属するインスタンスオブジェクトであり再帰関係を持つ。
MetaclassはMetaclass classのインスタンスオブジェクトでありMetaclass classは、Metaclassであり再帰関係を持つ。
基本的な派生元となるObjectやProtoObjectは、それらから派生したUndefinedObjectのインスタンスオブジェクトであるnilを継承しており再帰関係を持つ。
Smalltalk 言語は Smalltalk 言語自身によりメッセージ送信等の言語機能が制御される。
Smalltalk 言語の翻訳や仮想機械は Smalltalk 言語により実装される。
Smalltalk 言語の大域変数はSmalltalk変数に格納されたオブジェクトにより管理されるが、Smalltalk変数自体も大域変数である。
言語としてのSmalltalk > 言語仕様の種類

Smalltalk の言語仕様は原則として非常に単純なため、環境もしくは処理系の相違による互換の有無は、クラスライブラリーの差異程度に由来するもの（ある意味、バージョンの違いもこれも含まれる）から、言語仕様自体の改変に由来のものまで空間的に連続で多岐にわたる。このため、単に Smalltalk として語弊のある場合、一般にその環境および処理系の呼称もしくは商標（必要ならそのバージョン）をして他と区別するために用いる慣習がある。
言語としてのSmalltalk > 文法 > コメント

「"～"」のようにダブルクオーテーションでくくった文字列がコメントとして扱われる。
言語としてのSmalltalk > 文法 > 定数表現

主な定数表現には次のようなものがある。
| 型 | 例 |
| --- | --- |
整数: 3
整数(16進数): 16r3
小数: 3.4
浮動小数点数: 3.4e5
文字: $a
文字列: 'abc'
シンボル: #abc
記号を含むシンボル: #'*abc'
配列（要素は定数限定）: #( 'This' #is $a 10 )
バイト配列（要素は0〜255の定数限定）: #[ 0 255 16r0 16r255 ]
ブロック（引き数なし）: [ 3 + 4 ]
ブロック（引き数付き）: [ :x | x + 1 ]
定数ではないが、よく用いられるオブジェクトの生成式には次のようなものがある。
| 型 | 例 |
| --- | --- |
分数: 3 / 4
複素数: 3 + 4i
座標: 3 @ 4
共同体: 'a' -> 0
言語機能の様に見えるが「/」や「@」などはただのセレクターであり、Smalltalk の使用者も同様の機能を作ることが出来る。
言語としてのSmalltalk > 文法 > 変数

一時変数は宣言が必要で、「|」で挿むように記述する。変数への代入は「:=」。古い処理系では「_」が使用された（字形は「←」）。変数に型はなく全てハンドルになっている。
| a b |
a := 3.
b := 4.
言語としてのSmalltalk > 文法 > 擬変数

他の言語で予約語にあたる擬変数は self、super、nil、true、false、thisContext の6つ。self と super はそのメソッドを呼び出したメッセージの受け手（レシーバー）を、nil と true と false はそれぞれ UndefinedObject、True、False に属するソルインスタンス（唯一の実体）を、thisContext は実行中のコンテキスト（スタックフレーム）を参照するのに使える。
self と super は同種のオブジェクトだが、メッセージ式でメッセージレシーバーに指定されたときのメソッド検索の起点が異なり、self ではオブジェクトが属するクラス、super ではその基底クラスである。
言語としてのSmalltalk > 文法 > メッセージ式

Smalltalk では「メッセージ式」と呼ばれる書式でコードを記述する。メッセージ式は「レシーバー」に「メッセージ」を送ることを表すためのもので、そのまま
receiver message
と記述する。メッセージはさらに、呼び出されるされるメソッド（方法）の名前を表す「メッセージセレクター」と0個以上の引数の組み合わせからなる。ただし Smalltalk の場合必ずしもセレクターとメソッド名は一致しない。また、メッセージの送り先はメソッドではなくブロックや外部の関数になっている場合もある。セレクターは引数の数だけコロンを自身に含まなければならず、メッセージとして記述する際にはコロンの直後に引数を挿入する。
| メッセージ式 | セレクター | 引数 |
| --- | --- | --- |
| receiver noArg | noArg | N/A |
| receiver oneArg: arg | oneArg: | arg |
| receiver firstArg: arg1 secondArg: arg2 | firstArg:secondArg: | arg1、arg2 |
引数なしのメッセージを単項メッセージ、そのセレクターを単項セレクターと呼び、引数ありのメッセージをキーワードメッセージ、そのセレクターをキーワードセレクターと呼ぶ。メッセージ記述の際に引数の挿入により分断されたキーワードセレクター断片（例えば firstArg:secondArg: なら firstArg: と secondArg:）をキーワードと呼ぶが、あくまで便宜的な呼び名に過ぎず、そうした言語要素は存在しない。他の言語に見られる「キーワード引数」のように省略できるものではなく、また引数順を入れ替えられるものでもない。
セレクターは原則としてアルファベットと数字と0個以上（かつ、引数と同数）のコロンから成るが、例外として二項演算を模した記述が可能となるように記号のみから成る引数1つのセレクターを使ってメッセージ式を記述することもできる。これを二項メッセージ、そのセレクターを二項セレクターと呼ぶ。
| メッセージ式 | セレクター | 引数 |
| --- | --- | --- |
| 3 + 4 | + | 4 |
| #( 1 2 3 ), #( 4 5 ) | , | #( 4 5 ) |
この場合、上の「3 + 4」では、「3」がレシーバーで「+ 4」がメッセージである。
通常の処理系では、単項メッセージ、二項メッセージ、キーワードメッセージの順で評価される。二項メッセージ間で乗除の優先はない。
| メッセージ式 | 結合性を明示した等価の表現 |
| --- | --- |
3 + 4 * 5 min: 6 factorial: ( ( 3 + 4 ) * 5 ) min: ( 6 factorial )
セミコロン「;」でメッセージ式を区切る事により、1個のレシーバーに対して複数のメッセージを送ることが出来る。これをカスケード式という。
| collection |

collection := OrderedCollection
	new
	add: 0;
	add: 1;
	add: 2;
	add: 3;
	add: 4;
	yourself.
カスケード式を用いて書いた上記の文は、カスケード式を用いない次の文と等価である。
| collection |

collection := OrderedCollection new.
collection add: 0.
collection add: 1.
collection add: 2.
collection add: 3.
collection add: 4.
言語としてのSmalltalk > 文法 > 制御構文

複数の式を順次実行する場合は、式をピリオドで区切る。メソッドを中断し戻り値を指定するには復帰文「^ 戻り値式」を使う。言語機能として持つ制御構文は復帰文を除いて存在せず、復帰文以外の制御は制御構文と同等の機能を持ったメッセージ式で代用する。
言語としてのSmalltalk > 文法 > 制御構文 > ブロック

ブロックは、他の言語で言えば無名関数やクロージャーに該当する機能である。ただし Smalltalk のブロックは関数ではなくオブジェクトである事に加え、無名関数というより制御構文としての性格が強くなっている。並列実行の基本単位にもなる。
ブロックは、引き数の数毎に複数定義された「value」を含むメッセージを送る事で、ブロック内に記述されたメッセージ式を実行し結果を返す。
[                 　0               ] value.             "-> 0"
[ :value1         | value1          ] value: 1.          "-> 1"
[ :value1 :value2 | value1 + value2 ] value: 1 value: 1. "-> 2"
ブロック内の:value1 :value2は引き数であり、「|」以降は「value」を含むメッセージが送られた際実行するメッセージ式である。「value」を複数ならべたセレクターは4個程度まで( #value:value:value:value: )しか定義されておらず。5個以上引き数を取る場合は、配列を引き数とする#valueWithArguments:を使う必要がある。メソッドが値を返す際は、復帰文の記述が必要となるがブロックの場合は値を返すのに復帰文は必要ない。最後に実行されたメッセージ送信の結果あるいは、最後に書かれた値が戻り値となる。ブロックは制御の基本となるオブジェクトであるため、「value」を含むメソッド以外にも膨大なメソッドを持っている。ただし、後述する他の制御構文はブロックに対し#valueセレクターまたは、#value:セレクターを使ったメッセージしか送らない。
ブロックにはvalueと合わせてよく使われるセレクターとして「cull」がある。cullの振る舞いは、ほぼvalueと同じであるが、ブロックがメッセージに含まれる引き数を無視できるという違いがある。
[ :value1 | value1 ] cull: 1 cull: 2. "-> 1"
cullはブロックによる分岐制御が主目的であるが、分岐の基準になったオブジェクトを参照する場合もあるようなセレクターで使われる。典型的な例は、オブジェクトがnilで無いときだけブロックを実行する#ifNotNil:である。
| block value1 value2 |

block := [ :value | value ].

value1 := 1.
value2 := 2.

value1 ifNotNil: [ 9 ]. "-> 9"
value1 ifNotNil: block. "-> 1"
value2 ifNotNil: block. "-> 2"
言語としてのSmalltalk > 文法 > 制御構文 > 条件分岐

条件分岐は #ifTrue:ifFalse: セレクターを用いたメッセージ式として、条件式の結果の真偽値へのメッセージ送信の形で次のように記述する。
3 < 4 ifTrue: [ 5 ] ifFalse: [ 6 ].
Smalltalk では nil がオブジェクトである。これを利用した nil 専用の条件式も存在する。
object := nil.
object ifNil: [ 5 ] ifNotNil: [ 6 ].
object ifNotNilDo: [ :value | value inspect. ].
条件分岐の制御において、他の言語でいうswitchに直接該当する文は存在しない。多態性を利用して分岐するか、次のように連想配列を利用して分岐するため不要である。
something: aNumber
	| switch |

	"速度が求められる場合は、初期化済みのDictionaryのオブジェクトをインスタンス変数やクラス変数にキャッシュする。"
	switch := Dictionary
		new
		at: 1 put: [ #a ];
		at: 2 put: [ #b ];
		at: 3 put: [ #c ];
		yourself.

	^ ( switch at: aNumber ifAbsent: [ #z ] ) value.
但し一部の処理系では、次のようなswitchに類似した書き方ができるものも存在する。
something: aNumber

	^ aNumber caseOf:
	{
		[ 1 ]->[ #a ].
		[ 2 ]->[ #b ].
		[ 3 ]->[ #c ].
	}.
言語としてのSmalltalk > 文法 > 制御構文 > 反復

反復制御においてfor に直接該当する文は存在しない。代わりに回数を指定した反復がある。回数を指定した反復は、整数型へのメッセージ送信の形で次の様に記述する。
"100回の反復処理を実行する"
100 timesRepeat:
[
	"反復実行する処理"
].
現在の反復回数を参照しながら反復する事も出来る。
"100回の反復処理を実行する"
1 to: 100 do:
[ :each |
	"eachは現在の反復回数"
].
for　に該当する文は存在しないものの、while に該当する文は存在する。while に該当する反復は、ブロックに対するメッセージ送信の形で次の様に記述する。
[ true "真偽値を返す式" ] whileTrue:
[
	"反復実行する処理"
].
#whileTrue: セレクターは、条件が真である間反復する事を意味している。逆に条件が偽である間反復する #whileFalse: というセレクターも存在する。
また do-while に該当する文も存在する。do-while に該当する反復は、ブロックに対するメッセージ送信の形で次の様に記述する。
[
	"反復実行する処理"
	"このブロックの実行結果が真である間反復を繰り返す"
] whileTrue.
Smalltalk では条件なしの反復も存在する。無条件反復は、ブロックに対するメッセージ送信の形で次の様に記述する。
[
	"反復実行する処理"
] repeat.
Smalltalk では、反復方法が複数存在するが、実は全てメソッドの再帰呼び出しによって実装されているという事になっている。ただし、こちらも #ifTrue:ifFalse 同様実際にメソッドの再帰呼び出しとして実行されていない事が多い。
言語としてのSmalltalk > 文法 > 制御構文 > 反復からの脱出

C言語の break や Perl の last に相当する反復脱出は thisContext に対し #return セレクターを使ったメッセージを送る。
[
	thisContext return. "反復を抜ける"
] repeat.
thisContext には、引き数を取り、引き数を脱出するブロックの戻り値として返す #return: セレクターや、戻り先のメソッドを指定する #return:to: セレクターなど多数の return 系セレクターに対応するメソッドが定義されており、他の言語には珍しい多様な反復の脱出方法を備えている。
言語としてのSmalltalk > 文法 > 制御構文 > 例外処理機構

Smalltalk にも例外処理機構が存在する。こちらも、その他の構文と同じくメッセージ式とブロックによって実現されている。例外処理は次の様に記述する。
[
	[
		Exception signal: '処理失敗'. "例外発生"
	]
		ensure:
		[
			"例外の有無に関わらず実行したい処理"
		].
]
	on: Exception "補足する例外の種類"
	do:
	[ :exception |
		"例外を補足した際の処理"
	].
なお#ensure:は後述のブロックによる資源の開放があるため多用されることはない。
例外の制御はメッセージ送信毎に連結リストとして積み上げられたコンテキスト情報の末端のコンテキスト（メソッドスタック）を表す thisContext オブジェクトを操作し、コンテキストを巻き戻す事で実現されている。複数の例外は、#on:do:on:do・・とon:do:を繰り返し(処理系が定義している限りの数で)記述して補足する事もできるが、次の様に例外の型を,で並べて補足する事も出来る。
[
	Notification signal: '接続準備完了'. 
]
	on: Error, Notification
	do:
	[ :exception |
		"エラーと通知両方の例外を1度に補足"
	].
なお、Smalltalkでは正常な結果を返せない異常な状態と通知両方を合わせたものが例外である。例外は正常な戻り値を返せない異常な場合と割り込みの様に非同期な通知に利用される。特徴的な点として異常な場合と通知の場合では動作が異なる。異常な場合は他の言語の例外同様、補足しなければその時点で停止しDebugウィンドウに移行するが、通知の場合は補足しなければ例外発生地点から処理を継続する。
言語としてのSmalltalk > 文法 > 制御構文 > 並列処理

Smalltalkでは、標準で並列処理が存在する。並列処理は次の様に記述する。
| process semaphore |

semaphore := Semaphore new.
process :=
[
	Process yield. "他のProcessに切り替える切り替え点"
	"並列実行される子処理"

	semaphore signal. "親処理への終了通知"
] newProcess.

process resume.	"子処理の起動。Blockに対し#forkを送る場合はnewProcessとresumeは省略できる"
"並列実行される親処理"

semaphore wait. "子処理の終了待機"
並列処理はスレッドに類似するプロセスという仕組みにより実装されている。プロセスはSmalltalk環境内で構築された並列処理の仕組みであり、グリーンスレッドで実装されている事が多い。このため、プロセスは論理的に非プリエンプティブなスレッド(グリーンスレッド)を前提しており、現在実行している処理を切り替える切り替え点を必要とする。論理的な前提は非プリエンプティブではあるものの、POSIX環境で動作させたGNU Smalltalkの様に実際はプリエンプティブなスレッドで実装されている場合もある。プロセスは他のプロセスから割り込みとして任意の例外を投げる機能があり(記述方法は環境によって異なる)、切り替え点はプリエンプティブなスレッドを使う場合でも例外の発生地点として機能する。
言語としてのSmalltalk > 文法 > クラスオブジェクトの登録

Smalltalk は、クラスの定義をメッセージ式による実行環境へのクラスオブジェクトの登録として実現する。他の言語と異なりクラスオブジェクトの登録は単なる定義ではなく実行環境に対する操作である。1度クラスオブジェクトを登録してイメージファイルを保存すると、明示的にクラスオブジェクトを削除しないかぎりはクラスオブジェクトがイメージファイルに残り続ける。Smalltalk 環境に対するクラスオブジェクトの登録は次の様に記述する。
"DerivedクラスをSmalltalk環境に登録する例"
Object						"基底クラスオブジェクト"
	subclass:		        #Derived	"Objectクラスの派生として登録するクラスオブジェクト名の指定"
	instanceVariableNames:	'ia ib ic'	"インスタンス(実体)オブジェクトに所属する変数名(インスタンス変数)の指定(空白区切り)"
	classVariableNames:	    'ca cb cc'	"クラスオブジェクトと共有する変数名(クラス変数)の指定(空白区切り)"
	poolDictionaries:	    'pa pb pc'	"クラスに所属する変数(プール変数)を取り込む辞書の指定(空白区切り)"
	category:		        'example'.	"Smalltalk環境上でクラス名を表示する際にクラスが所属する分類の指定"
poolDictionaries と category を除いては、C++ から派生した言語のクラス定義と概ね同じである。インスタンス変数はインスタンスメソッドのみから参照でき、クラス変数はクラスメソッドとインスタンスメソッドから参照できる。他の言語と異なりインスタンス変数をクラスメソッドから参照することはできない。
Smalltalk におけるクラスの作成は、特殊構文ではなく単なるメッセージ送信である。クラスを登録する際のメッセージは、上記の例のように次のセレクターを使用することが多い。
#subclass:instanceVariableNames:classVariableNames:poolDictionaries:category:
しかし、クラスの登録はあくまでメッセージであり自由に作れるため、実行環境には大抵その他のメソッドが用意されている。例えば、近代的な Smalltalk 環境の一つ Pharo では、次のセレクターに対応したメソッドが用意されている。
#subclass:
#subclass:category:
#subclass:instanceVariableNames:
#subclass:instanceVariableNames:classVariableNames:poolDictionaries:category:
#subclass:uses: 
#subclass:uses:instanceVariableNames:classVariableNames:poolDictionaries:category:
#variableByteSubclass:instanceVariableNames:classVariableNames:poolDictionaries:category:
#variableByteSubclass:uses:ginstanceVariableNames:classVariableNames:poolDictionaries:category:
#variableSubclass:instanceVariableNames:classVariableNames:poolDictionaries:category:
#variableSubclass:uses:ginstanceVariableNames:classVariableNames:poolDictionaries:category:
#variableWordSubclass:instanceVariableNames:classVariableNames:poolDictionaries:category:
#variableWordSubclass:uses:ginstanceVariableNames:classVariableNames:poolDictionaries:category:
#weakSubclass:instanceVariableNames:classVariableNames:poolDictionaries:category:
#weakSubclass:uses:ginstanceVariableNames:classVariableNames:poolDictionaries:category:
クラスオブジェクトには、クラス変数とは別途、クラスオブジェクトが Class クラスから派生したインスタンスとして状態を持つためのインスタンス変数がある。このクラスオブジェクトのインスタンス変数はクラスオブジェクト内だけで共有され、インスタンスオブジェクトからは直接使用できない。
Smalltalk 環境に対するクラスオブジェクトのインスタンス変数の登録は次の様に記述する。
Derived class instanceVariableNames: 'ia ib ic'. "クラスオブジェクトのインスタンス変数名(空白区切り)"
クラスオブジェクトがもつインスタンス変数には変数を登録した基底クラスと派生クラスで別々の変数領域が確保されるという特筆すべき点がある。これを使用して下記の様にクラスに所属するオブジェクトだけを保持する変数としてつかったりする事ができる。
Object subclass: #Super.
Super class instanceVariableNames: 'objects'.

Super class methodsFor: 'accessing'
!
objects

    ^ objects ifNil: [ objects := OrderedCollection new ].
!!

Super class methodsFor: 'instance creation'
!
new
    | object |
    
    object := super new.
    self objects add: object.
    ^ object.
!!

Super subclass: #Derived. 

Derived new.
Derived objects size. "-> 1"
Super objects size. "-> 0"
言語としてのSmalltalk > 文法 > メソッドの登録

メソッド（処理方法）の登録は、コード文字列を引数として与えたクラスへのメッセージ送信でも行えるが、通常は環境に組み込まれたクラスブラウザ（システムブラウザ）と呼ばれるGUIツールを用いる。
メソッドは、「メッセージパターン」と呼ばれるメッセージ式のメッセージ部分を模した書式に続けて0個以上のメッセージ式を連ねることで記述する。例えば、前出の、レシーバーか引数を比べてより小さな方を返す「min:」というメソッドの登録は次のようなものになる。
min: anOtherObject
	^ self < anOtherObject ifTrue: [ self ] ifFalse: [ anOtherObject ].
一行目の「min: anOtherObject」がメッセージパターンで、メソッド名（セレクター）と仮引数となる擬変数の宣言を兼ねる。念のためここでメソッド名は「min:」、仮引数となる擬変数名は「anOtherObject」である。仮引数は仮引数自体の書き換えは不能なハンドル渡しとなっている。メッセージパターンのあとに処理を続けて書くこともできるが、通常は行を改めて（さらに、ここでは省いたが慣習としてメソッドの説明をするコメントを書き、それに続けて）処理を記述する。
なお、メッセージパターンのみで具体的な処理を記述せずにメソッドを登録した場合を含め、復帰文による明示的な戻り値の指定が無い場合、メソッドは戻り値として常に self を返す。したがって Smalltalk では値を返さないメソッドを書くことはできない。
言語としてのSmalltalk > 文法 > クラスオブジェクト

Smalltalkは、多くの動的型付け言語やDelphiの様にクラスがオブジェクトである。このためSmalltalkではインスタンスオブジェクトと同様にクラスオブジェクトを変数に束縛してメッセージを送ることができる。
| object |

object := Something new.
object value. "インスタンスオブジェクトにvalueメッセージを送信"
object := Something.
object value. "クラスオブジェクトにvalueメッセージを送信"
クラスオブジェクトは、オブジェクトにclassメッセージを送ることでも取得できる。
' ' class. "-> ByteString"
言語としてのSmalltalk > 文法 > 復帰文とブロック

Smalltalk のブロックは一種の制御構文であるという性質上、復帰文が他の言語と比べ極めて異質な振る舞いをする。
example
	| block |

	block := [ ^ 1 ].
	block value. "ブロックを実行"
	^ 0.
上記のメソッドを登録したオブジェクトに#example セレクターを使ったメッセージを送ると結果としては何が返ってくるか。Smalltalk 以外の言語では 0 が返ってくるのが一般的であるが Smalltalk では 1 が返ってくる。Smalltalk はブロック内の復帰文からでもメソッド自体を抜けることができるようになっている。この例では、「block value.」を評価し、block 中の「^ 1.」で制御が戻ると example 自体も中断して結果を返す。そして example は戻り値として block が戻した 1 を戻すようになっている。
callee: aBlock
	aBlock value.
	^ 2.
caller
	| block |

	block := [ ^ 1 ].
	self callee: block.
	^ 0.
上記の様なメソッドをまたいでブロックを評価する場合はどうなるだろうか、この場合も Smalltalk は example の戻り値として block の戻り値である1を返す。Smalltalk はブロック内で復帰文が実行された際、ブロックの生成地点の呼び出し元までコンテキストを巻き戻すようになっている。この特性により Smalltalk では、#ifTrue:ifFalse: セレクターを使った分岐でメソッドを中断したり #repeat セレクター等を使った反復処理を復帰文だけで中断する事ができるようになっている。
exampleBlock
	^ [ ^ 1 ].
callee: aBlock
	aBlock value.
	^ 2.
caller
	| block |

	block := self exampleBlock.
	self callee: block.
	^ 0.
ただし、上記の様にブロックを生成したコンテキストと、ブロックを評価する際のコンテキストが枝分かれする様な場合は復帰文を実行する事はできない。この場合は BlockContext が例外を出力し処理が停止してしまう。
言語としてのSmalltalk > 文法 > メソッドに対する注釈

メソッドに対する注釈(Pragma)は、メッセージ式だけではどうしても実現が難しい機械語でしか記述できない演算子の実装や主記憶領域の確保、仮想機械外部との入出力等の実現や、特定の目的のメソッドを自動で列挙するといった目的で使用される特殊構文である。いくつかの注釈はSmalltalk環境に組み込まれているが、利用者やライブラリーの提供者が注釈を定義する事も出来る。
メソッドに対する注釈はメソッドの翻訳時に評価されるため、メソッドにしか記述でない。Behaviorのevaluate:による評価などメッセージ式をメソッドの外部で評価する場合は、評価対象の式に注釈を含める事はできない。具体的にはSmalltalk環境のWorkspaceに注釈を記述して評価するとエラーとなる。
メソッドに対する注釈は次の様に記述する。
< keyword1: arg1 ... keywordN: argN >
<と>で囲まれた範囲は、メッセージ式のメッセージ部分と同じになる。但し引き数を取らない注釈の記述はできない。
次にメソッドに対する注釈の具体例を挙げる。注釈はSmalltalk環境によって異なり、どの環境でも次の注釈が使えるわけでない事に注意すること。
| コード | 意味 |
| --- | --- |
<primitive: 1>: 数値演算など原子的機能の呼び出し。引き数の値は呼び出す機能の番号。
<apicall: int 'GetLastError' () module: 'kernel32.dll'>: FFIによる外部関数の呼び出し。先頭のapicallは呼び出し規約であり注釈の名前ではない。cdeclなどもある。
言語としてのSmalltalk > 文法 > 大域変数

Smaltallkでは、Smalltalk環境全体で参照できる大域変数を作成する事が出来る。大域変数は同じく大域変数であるSmalltalk変数に格納されたSmalltalkImageのインスタンスオブジェクトにメッセージを送って作成する。また、大域変数の削除もSmalltalkImageのインスタンスオブジェクトに対するメッセージ送信となっている。
Smalltalk at: #GlobalVariable put: 100.
GlobalVariable. "->100"

globalVariable := 10.
Smalltalk at: #GlobalVariable. "->10"

Smalltalk removeAt: #GlobalVariable.
GlobalVariable. "->nil"
SmalltalkImageは一種の連想配列であり、Smalltalkの大域変数は、Smalltalk変数を介す事で連想配列として操作する事が出来るようになっている。
なお、Smalltalkのクラス名と大域変数は同じものであり、クラス名にオブジェクトを代入すれば、そのクラスを破壊してしまうことが出来る。また、Smalltalkオブジェクトが格納されたSmalltlak変数もオブジェクトを代入し破壊する事が出来る。このように大域変数を代入により破壊してしまった場合は、最悪Smalltalk環境が起動しなくなる事態に陥り非常に危険である。このためSmalltalkではよほどの理由がなければ大域変数を使うべきではない。
言語としてのSmalltalk > 文法 > プール辞書

プール辞書は、クラスの変数として連想配列または、他のクラスオブジェクトのクラス変数を取り込むという機能である。取り込む連想配列の要素やクラスオブジェクトのクラス変数はプール変数と呼ばれる。連想配列やクラスオブジェクトは大域変数でなくてはならない。
"プール辞書で使用する連想配列の登録"
Smalltalk at: #UserPoolA put: Dictionary new.
UserPoolA at: #ExamplePoolValueA put: 1.

"プール辞書で使用するクラスオブジェクトの登録"
Object
	subclass:		#UserPoolB
	instanceVariableNames:	''
	classVariableNames:	'ExamplePoolValueB'
	poolDictionaries:	''
	category:		'example'.

"UserPoolAとUserPoolBをプール変数として利用するクラスオブジェクト"
Object
	subclass:		#Someone
	instanceVariableNames:	''
	classVariableNames:	''
	poolDictionaries:	'UserPoolA UserPoolB'	"UserPoolAとUserPoolBを辞書に記述しプール変数を取り込む"
	category:		'example'.

Someone methodsFor: 'accessing'
!
valueA
	^ ExamplePoolValueA. "UserPoolAのExamplePoolValueAを参照"
!
valueB

	^ ExamplePoolValueB. "UserPoolBのExamplePoolValueBを参照"
!!
プール辞書には複数の連想配列やクラスオブジェクトを指定できるが、プール変数が重複した場合は、先に指定した連想配列やクラスオブジェクトのプール変数が使われる。
言語としてのSmalltalk > 準標準的な文法 > 非定数要素配列

Pharo, GNU Smalltalkといった近代の環境では、定数以外に式の結果を指定可能な非定数要素の配列定数を使用できる。配列の要素は空白ではなく.で区切る。
array := { 1. 1 + 1 }. "1と2を要素に持つ配列を作る。"