Smalltalk

出典: Wikipedio


Template:Infobox プログラミング言語

Template:プログラミング言語 Smalltalk(スモールトーク)は、Simulaオブジェクト(およびクラス)、Lispの機能、LOGOのエッセンスを組み合わせて作られたクラスベースの純粋オブジェクト指向プログラミング言語、および、それによって記述構築された統合化プログラミング環境の呼称。

Smalltalkで一語であり、Small TalkSmallTalkなどは誤りである。ただし、この名前の由来である、世間話・雑談を意味する英語は、small talk である。

目次

開発の経緯

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

Smalltalkとオブジェクト指向

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

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

Smalltalk環境の独自性

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

これはVisualWorksやSqueakなど、旧来のSmalltalk環境、つまりDynabookコンピュータ環境の要素を引き継ぐIDEを通じてSmalltalk言語や処理系を学ぶなら、多かれ少なかれ新たなOSに接するような心構えを持つべきことを意味する。

環境および処理系

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

  • Smalltalk-72
  • Smalltalk-74
  • Smalltalk-76
  • Smalltalk-78
  • Smalltalk-80
  • ObjectWorks
  • VisualWorks
  • Squeak
  • VisualAge Smalltalk
  • Little Smalltalk
  • GNU Smalltalk
  • Dolphin Smalltalk
  • #Smalltalk
  • SmallScript (S#)
  • Smalltalk MT
  • Smalltalk/V
  • Smalltalk/X
  • Concurrent Smalltalk
  • Distributed Smalltalk
  • Strongtalk
  • PIC/Smalltalk
  • Smalltalk/JVM
  • Smalltalk Express
  • Ambrai Smalltalk

文法

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

<source lang="smalltalk"> receiver message </source>

と記述する。メッセージはさらに、コールされるメソッドの名前を表わす「メッセージセレクタ(あるいは単にセレクタ)」と0個以上の引数の組み合わせからなる。セレクタは引数の数だけコロンを自身に含まなければならず、メッセージとして記述する際にはコロンの直後に引数を挿入する。

<source lang="smalltalk"> "メッセージ式" "セレクタ" "引数" receiver noArg "noArg" "なし" receiver oneArg: arg "oneArg:" "arg" receiver argOne: arg1 argTwo: arg2 "argOne:argTwo:" "arg1, arg2" </source>

引数なしのメッセージを「単項メッセージ」、そのセレクタを「単項セレクタ」と呼び、引数ありのメッセージを「キーワードメッセージ」、そのセレクタを「キーワードセレクタ」と呼ぶ。メッセージ記述の際に引数の挿入により分断されたキーワードセレクタ断片(たとえば argOne:argTwo: なら argOne: と argTwo:)を「キーワード」と呼ぶが、あくまで便宜的な呼び名に過ぎず、そうしたエンティティがあるわけでも、他の言語に見られる「キーワード引数」のような意味や機能(引数順を入れ替えられる⋯とか)があるわけでもない。

セレクタは原則としてアルファベットと数字と0個以上(かつ、引数と同数)のコロンから成るが、例外として二項演算を模した記述が可能となるように記号のみから成る引数ひとつのセレクタを使ってメッセージ式を記述することもできる。これを「二項メッセージ」、そのセレクタを「二項セレクタ」と呼ぶ。

<source lang="smalltalk"> "メッセージ式" "セレクタ" "引数" 3 + 4 "+" "4"

  1. (1 2 3), #(4 5) "," "#(4 5)"

</source>

この場合、上の「3 + 4」では、「3」がレシーバで「+ 4」がメッセージである。

通常の処理系では、単項メッセージ > 二項メッセージ > キーワードメッセージの順で評価される。二項メッセージ間で乗除の優先はない。

<source lang="smalltalk"> 3 + 4 * 5 min: 6 factorial "== ((3 + 4) * 5) min: (6 factorial)" </source>

テンポラリ変数は宣言が必要で、| で挿むように記述する。変数への代入は「:=」。古い処理系では「_」が使用された(グリフは「←」)。複数の式を順次実行する場合は、式をピリオドで区切る。処理を中断し戻り値を指定するには「^ 戻り値式」(リターン)を使う。

<source lang="smalltalk"> | a b | a := 3. b := 4. ^a + b </source>

制御構文は「リターン」を除いて存在しない。たとえば if-then-else なら ifTrue:ifFalse: セレクタを用いたメッセージ式として、条件式の結果の真偽値へのメッセージ送信のかたちで次のように記述する。

<source lang="smalltalk"> 3 < 4 ifTrue: [5] ifFalse: [6] </source>

ただ、多くの処理系では条件式やループ式はバイトコードレベルでインライン展開される(ジャンプ命令の表現に置き換えられる)ため、実際に、例えば上のコードを評価した場合に「ifTrue: [5] ifFalse: [6]」というメッセージが送られるわけではなく、ひいては ifTrue:ifFalse: という名のメソッドがコールされることもないということは、いずれ知っておく必要がある。

主なリテラル表現には次のようなものがある。

<source lang="smalltalk"> "整数" 3 "小数" 3.4 "浮動小数点数" 3.4e5 "文字" $a "文字列" 'abc' "シンボル" #abc "配列(要素はリテラル限定)" #('This' #is $a 10) "ブロック(パラメータなし)" [3 + 4] "ブロック(パラメータ付き)" [:x | x + 1] </source>

リテラルではないが、よく用いられるオブジェクトの生成式には次のようなものがある。

<source lang="smalltalk"> "分数" 3 / 4 "複素数" 3 + 4i "座標" 3 @ 4 </source>

なお、コメントは "..." とダブルクオーテーションで括る。

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

selfとsuperは同じオブジェクトだが、メッセージ式でメッセージレシーバに指定されたときのメソッドサーチの起点が、オブジェクトが属するクラスから(selfの場合)か、そのスーパークラスから(superの場合)かで異なる。

メソッドの定義は、コード文字列を引数として与えたクラスへのメッセージ送信でも行なえるが、通常は環境に組み込まれたクラスブラウザ(システムブラウザ)と呼ばれるGUIツールを用いる。

メソッドの定義コードは、「メッセージパターン」と呼ばれるメッセージ式のメッセージ部分を模した書式に続けて0個以上のメッセージ式を連ねることで記述する。たとえば、前出の、レシーバか引数を比べてより小さなほうを返す「min:」というメソッドの定義は次のようなものになる。

<source lang="smalltalk"> min: other

  ^self < other ifTrue: [self] ifFalse: [other]

</source>

一行目の「min: other」がメッセージパターンで、メソッド名(セレクタ)と仮引数となる擬変数の宣言を兼ねる。念のためここでメソッド名は「min:」、仮引数となる擬変数名は「other」である。メッセージパターンのあとに処理を続けて書くこともできるが、通常は行を改めて(さらに、ここでは省いたが慣習としてメソッドの説明をするコメントを書き、それに続けて)処理を記述する。

なお、メッセージパターンのみで具体的な処理を記述せずにメソッドを定義した場合を含め、リターンによる明示的な戻り値の指定が無い場合、メソッドは戻り値として常にselfを返す。したがってSmalltalkでは値を返さないメソッドを書くことはできない。an:Smalltalk bg:Smalltalk ca:Smalltalk cs:Smalltalk de:Smalltalk-80 (Programmiersprache) el:Smalltalk en:Smalltalk es:Smalltalk et:Smalltalk fa:اسمال‌تاک fi:Smalltalk fr:Smalltalk he:Smalltalk id:Smalltalk it:Smalltalk ko:스몰토크 lv:Smalltalk nl:Smalltalk no:Smalltalk pl:Smalltalk pt:Smalltalk ru:Smalltalk sk:Smalltalk sl:Smalltalk sv:Smalltalk tg:Smalltalk th:ภาษาสมอลล์ทอล์ก tr:Smalltalk uk:Smalltalk vi:Smalltalk zh:Smalltalk

個人用ツール