(スモールトーク)は、 のオブジェクト(およびクラス)、の徹底した動的性、 のタートル操作や描画機能に、アラン・ケイの「メッセージング」というアイデアを組み合わせて作られたクラスベースで手続き型の純粋オブジェクト指向プログラミング言語、および、それによって記述構築された統合化プログラミング環境の呼称。

で一語であり、「」「」などは誤りである。

大規模な開発実績としてはCargill Lynx Projecthttps://www.infoq.com/jp/news/2010/07/objects-smalltalk-erlangがあり、国産製品の開発実績としてはMCFrameがある。

概要 開発の経緯 ゼロックスのパロアルト研究所()で1970年代に約10年かけ3世代(-72、76、)を経て整備された。当初は、ダイナブックである のオペレーティングシステム的位置付けだったが、 のゼロックス社製品としての販売の可能性が同社上層部決定により完全に排除されたこと、発案者であるアラン・ケイの研究開発グループ離脱などを受けてダイナブック色は失せ、 のハードウェア技術を基にした商用マシン上で動作するプロの開発者向け統合化プログラミング環境「80」として1983年に発売されることになる。現在はシンコムより という製品名で主要なオペレーティングシステム向けに販売されている。

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

とオブジェクト指向 豊富で整備されたクラスライブラリーは、特にオブジェクト指向プログラミングの手本とされ、デザインパターンの宝庫と称されるまで洗練されたものになっている。また、後世の多くのオブジェクト指向プログラミング言語に直接間接的に多大な影響を与えた。

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

の独自性 は、オブジェクトへのメッセージ送信を率直に記述する表記の特殊性や、制御構造をもたずオブジェクトへのメッセージ送信の形で記述する徹底ぶりとも併せて、C言語や などの流れを強く受け継ぐ言語、およびその開発手法に慣れた開発者にとって極めてとっつきにくい言語・環境であるといわれている。このことは、 が単なるプログラミング言語ではなく、従来のオペレーティングシステムの概念をも包括する「環境」であることが一つの理由である。 を単なる言語としてとらえると、他の言語と比較したとき、使用するオペレーティングシステムのグラフィカルユーザインタフェースに全く従わないなど、その独自性が大きな「欠点」として映る場合もある。

これは や など、旧来の 環境、つまりダイナブックコンピュータ環境の要素を引き継ぐ統合開発環境を通じて 言語や処理系を学ぶなら、多かれ少なかれ新たなオペレーティングシステムに接するような心構えを持つべきことを意味する。

環境および処理系としてのSmalltalk 環境から見た 言語 環境から見た 言語は、いわば などのシェルに近い。 環境内であればどこでもマウスで選択した文字列を のソースコードとして実行できるためシェルにコマンドを打ち込んだ時の様に簡単な問い合わせをすぐ実行できるようになっている。

例えばオブジェクト(クラスやメソッドも含む)の構造を調べたければ、そのオブジェクトにセレクターあるいはセレクターを使ったメッセージ式を書き、そのメッセージ式をマウスで選択してdo it(WindowsであればCtrl+Dを押す)すれば良い。

また、設定値の指定に 言語のメッセージ式が使われる。現在設定されている値がメッセージ式として取得でき、値の設定をメッセージ式として指定する。この設定値を指定するメッセージ式は 環境の実行中に設定用のウィンドウから入力される。

仮想マシン方式 仮想マシンによる実行 環境は、 環境の実行方法として現実のハードウェアに依存している機械語命令を使わず、現実のハードウェアから独立した中間言語命令(仮想マシンに対する機械語命令)を仮想マシンにより実行する仮想マシン方式を採用している。 の中間言語命令は、全てイメージファイルというファイルに書き込まれ の仮想マシンはそのイメージファイルを読み込んで 環境を実行する。

この仮想マシン方式による の実行方法は の言語仕様にも含まれている。http://stephane.ducasse.free.fr/FreeBooks/BlueBook/Bluebook.pdf なお、 が導入したこの仮想マシン方式はのpコードマシンからアラン・ケイが着想を得たものである。http://worrydream.com/EarlyHistoryOfSmalltalk/

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

仮想マシンとブートストラップ の実行環境が全く存在しない初期の状況ではコンパイラも仮想マシンも で用意する事はできない。このため の初期段階ではALTOのアセンブリ言語によりコンパイラや仮想マシンが実装されていた。Reviving Smalltalk-78

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

環境の種類

+ Smalltalk環境の種類環境使用している仮想マシン有償版無償版CPUOS備考-○○http://www.cincomsmalltalk.com/main/developer-community/trying-cincom-smalltalk/try-cincom-smalltalk/-Win2017年現在VisualWorksを販売するCincomのWindows向け製品となっている。○○x86/x64Unix/Linux/OSX/Winゼロックス時代のSmalltalkを引き継ぐSmalltalk環境。名前空間http://smalltalk.cincom.jp/tutorials/primers/Introduction/Namespace.sspやイメージファイルからモジュールを切り離せるパーセルhttp://smalltalk.cincom.jp/tutorials/vw7.7/tutorial2/vwparcels2.ssp、OSのデスクトップ上に表示できるウィンドウ等以前のSmalltalkより大きく拡張されている。2017年現在も活発に開発されている。×○x86Unix/Linux/OSX/WinApple Smalltalkから派生したプラットフォーム非依存やマルチメディア対応を強化したSmalltalk環境。Pharo×○x86/x64/ArmUnix/Linux/OSX/Win/MacOSSqueakから開発向けに派生したSmalltalk環境。http://www.pharo-project.org/about-○○x86/x64Unix/Linux/OSX/Winデータベース管理システムとしての用途に特化したSmalltalk環境。その用途からGUIは無い。2017年現在GemTalk systemにて無償版が配布されている。2017年現在も活発に開発されている。GNU Smalltalk-×○x86/x64/armUnix/Linux/Android/OSX/WinGUI無しでの開発に特化しており他の環境ではGUIを前提としている機能をCUIで実行できる。ただしGUI環境も用意されている。Cと連携するための機能が他の処理系と比較して特に強力であり、関数のポインタを指定すべき引数にブロックを渡したり、関数呼出もできる各種ポインタ操作ができるようになっている。しかも、関数のポインタとして渡すブロックは変数を束縛した状態で渡す事が可能になっている。-×○-Win言語仕様に静的型検査を追加したSmalltak環境。Hot spotによる最適化を初めて実装したVMで極めて高速に動作する。Strongtalkで開発されたHot spot技術はJavaVMなどにも移植されたhttp://strongtalk.org/×○x64Unix/Linux/OSX/WinPharoの環境を元に言語仕様に静的型検査と動的型検査を追加したSmalltak環境。http://pleiad.cl/research/software/gradualtalk-×○Web Browserに依存Web Browserに依存Web Browser上で動作するSmalltalk環境。http://amber-lang.net/----WinWindowsに特化しておりOS固有の機能やOS固有のGUIを使用できる。OSとの親和性が高い。http://www.object-arts.com/downloads/docs/index.htmlhttp://www.object-arts.comSmalltalkからJavaを呼び出すJNIPortを最初に実装した処理系であり、JNIPortが使える処理系ではDolphin Smalltalkの名前を目にする機会が多い。https://sites.google.com/site/jniport/documentation/jniport-for-visualworks---Java VMに依存Java VMに依存Java VMを使用する。http://missionsoft.com/---共通言語基盤に依存共通言語基盤に依存.NET Frameworkを使用する。http://www.refactory.com/tools/sharp-smalltalk----UnixUnixで動作するSmalltalk環境。-----pc98で動作するSmalltalk環境。VisualAge-----からIBMが派生させて開発したSmalltalkベースの統合開発環境。Javaで記述されたEclipseの原型でもある。VA Smalltalk - - - - -IBMが開発を停止したVisualAgeの派生製品。2018年現在も開発が継続されている。----WinWindowsに特化しActive Xを生成できる。http://www.objectconnect.com/stmtvc_info.htm-----Smalltalk環境として稼働する上で必要最低限の機能だけを備えるSmalltalk環境。()-----------------アクターモデルによる分散処理を導入した環境。---------------------80386SX以上-pc98で動作するSmalltalk環境。動作環境として、CPU 80386SX以上、メモリ3.6Mbyte(V2.5Jでは4.6Mbyte)以上搭載、ハードディスク空き容量5Mbyte(同10Mbyte)以上とされるが、当時のマシン環境としてPC-9801DA21に7.6Mbyte以上のメモリと80Mbyte以上のハードディスクを装備した環境を推奨。

GUIツール

準標準的なGUIツール GUIを使わないような特殊なものを除き、大半のSmalltalk環境では次のようなGUIツールが用意されている。

Class Browser(System Browser) Transcript Workspace Debugger/Notifier Inspector Smalltalkの開発ではこれらのツールを使って開発する事が半ば前提となっている。

Class Browser(System Browser) Smalltalk環境内に存在する全てのクラスを(存在する場合は名前空間も)表示/編集できるツールで、Smalltalk開発において中核となるツールである。

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

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

Debugger/Notifier

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

言語としてのSmalltalk 言語としての設計思想 言語として が目指したもの。それは計算機を計算機の集合体として構築し、さらに計算機を構成する個々の計算機も計算機の集合体で構築するというように、再帰的な計算機を構築することであった。この再帰的な計算機を構築している無数の計算機は、個々の内部には干渉せずメッセージによる通信のみによって相互作用を発生させ目的の計算を完遂させる。

ここでいう計算機が ではオブジェクトという形で実装された。

この設計思想の誕生は、とB5000の設計者らが会談した際の次の発言をアラン・ケイが聞き「計算機の全体を計算機とみなした場合、その計算機の構成要素を計算機に分解するのではなく関数やデータ構造に分解したいと誰が思うのか」と疑問を浮かべた事がきっかけとなっている。

ここで言及された再帰という概念は、オブジェクトの成立以外にも の至るところに影響を与えている。 反復はメソッドの再帰呼び出し。 インスタンスオブジェクトを生成しているクラスオブジェクトも、クラスオブジェクトに所属するインスタンスオブジェクトであり再帰関係を持つ。 MetaclassはMetaclass classのインスタンスオブジェクトでありMetaclass classは、Metaclassであり再帰関係を持つ。 基本的な派生元となるObjectやProtoObjectは、それらから派生したUndefinedObjectのインスタンスオブジェクトであるnilを継承しており再帰関係を持つ。 言語は 言語自身によりメッセージ送信等の言語機能が制御される。 言語の翻訳や仮想マシンは 言語により実装される。 言語の大域変数は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

言語機能の様に見えるが「/」や「@」などはただのセレクターであり、 の使用者も同様の機能を作ることが出来る。

変数 一時変数は宣言が必要で、「|」で挿むように記述する。変数への代入は「:=」。古い処理系では「_」が使用された(字形は「←」)。変数に型はなく全てハンドルになっている。

| a b | a := 3. b := 4.

擬変数 他の言語で予約語にあたる擬変数は self、super、nil、true、false、thisContext の6つ。self と super はそのメソッドを呼び出したメッセージの受け手(レシーバー)を、nil と true と false はそれぞれ UndefinedObject、True、False に属するソルインスタンス(唯一の実体)を、thisContext は実行中のコンテキスト(スタックフレーム)を参照するのに使える。

self と super は同種のオブジェクトだが、メッセージ式でメッセージレシーバーに指定されたときのメソッド検索の起点が異なり、self ではオブジェクトが属するクラス、super ではその基底クラスである。

メッセージ式 では「メッセージ式」と呼ばれる書式でコードを記述する。メッセージ式は「レシーバー」に「メッセージ」を送ることを表すためのもので、そのまま

receiver message

と記述する。メッセージはさらに、呼び出されるされるメソッド(方法)の名前を表す「メッセージセレクター」あるいは単に「セレクター」。と0個以上の引数の組み合わせからなる。ただし の場合必ずしもセレクターとメソッド名は一致しない。また、メッセージの送り先はメソッドではなくブロックや外部の関数になっている場合もある。セレクターは引数の数だけコロンを自身に含まなければならず、メッセージとして記述する際にはコロンの直後に引数を挿入する。

メッセージ式セレクター引数receiver noArgnoArgreceiver oneArg: argoneArg:argreceiver firstArg: arg1 secondArg: arg2firstArg: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.

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

ブロック ブロックは、他の言語で言えば無名関数やクロージャーに該当する機能である。ただし のブロックは関数ではなくオブジェクトである事に加え、無名関数というより制御構文としての性格が強くなっている。並列実行の基本単位にもなる。

ブロックは、引き数の数毎に複数定義された「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.