今回から2回にわたりプログラミング言語「Smalltalk」についてお話しします。Smalltalkと言えば、オブジェクト指向プログラミング言語と、開発環境と実行環境を統合したようなプログラミング環境が大きな特徴です。そこで前編はSmalltalkの登場背景とオブジェクト指向プログラミング言語としての特徴的な構文、後編はプログラミング環境を取り上げます。
生まれはパロアルト研究所
Smalltalkは1970年代にXerox社のパロアルト研究所(以降はPARCと称す)で、アラン・ケイ率いる学習研究グループにより作成されました。PARCと言えば、レーザープリンタ、インターネットの基礎となるイーサネット(ethernet)、そしてSmalltalkが深く関係するパーソナルコンピュータのアルトを生み出した伝説的な研究所です[1]。メインフレームやミニコンピュータが主流の時代に、机のキャビネットサイズで、ディスプレイ、キーボード、そしてマウスが一体となった個人専用マシンのアルトが誕生したのですから驚きですね。
ダイナブックの理想のもとに
もともとアルトは、アラン・ケイがコンピュータのあるべき姿(=メディア)として思い描いたダイナブック[2]を目指して開発されものでした。
ダイナブックが成し遂げたかった仕様とは、次のようになります。
- ノート程度の大きさ
- 子供でも持ち運べる
- 絵から楽譜に至るまで、いろいろな情報を出し入れできる
- 直感的な操作ができる
つまりユーザが求める操作に即座に対応できる装置といえます。しかし、残念ながら当時のハードウェア技術ではダイナブックのすべてを実現できませんでしたが、それでもアルトは誕生しました。
Smalltalkの誕生
ケイはソフトウェア面からダイナブックにアプローチし、誰でもプログラミングできることを目指してプログラミング言語を設計しました。そして同じ学習研究グループのダニエル・H・インガルズやアデル・ゴールドバーグらの実装により完成したのがSmalltalkです。SmalltalkはアルトにGUI環境を提供し、現在のGUI環境の基礎となるオーバーラッピングウィンドウやポップアップメニューなどの優れたアイデアを実現しました。これはコマンドベースのユーザインタフェースしかなかった当時からすると画期的なことでした。 Smalltalkを搭載したアルトは暫定版ダイナブックと呼ばれました。
暫定版ダイナブックは当時もの凄い代物だったにも関わらず、上層部の理解が得られず、Xerox社から販売されることは永遠にありませんでした。代わりにGUI環境の優れたアイデアは、暫定版ダイナブックを視察に訪れたアップルが販売したパーソナルコンピュータのLisa(これが後のMacにつながる)により世界に知れ渡ることとなりました。一方、Smalltalkは1983年にSmalltalk-80としてXerox社から販売されました。
みんなのSmalltalk
本講座の第3回「LOGO」で触れてたように、ケイはLOGOの影響を強く受けていたので、暫定版ダイナブックにさまざまな人(特に子供達)に試用してもらい、フィードバックを集め、Smalltalkを洗練していきました。
この試用では、少女は図形を描くドローツール、高校生は電気回路のレイアウトを行うシステム、そして音楽家は譜面を作成するシステムなど、プログラマでない人がシステムを作成したのです。自分の用途に応じたアプリケーションを誰もがプログラミングできるほど、Smalltalkは本当にシンプルに設計されたのです。
Smalltalkのプログラミングをしてみよう
Smalltalkは、コマンドを入力し命令するとタートルが反応するというLOGOのシンプルな操作環境、1960年代に作成されたSIMULAのクラスやオブジェクトの影響を受け、全ての命令はオブジェクトにメッセージを送ることで行う、オブジェクト指向プログラミング言語として設計されました。
Smalltalkの特徴的な構文を見ていきます。なお、ここからの説明はSqueakというSmalltalk-80の直系にあたる環境を基に進めます。そのため標準のSmalltalkと一部異なる表記を使用しているので、他のSmalltalkの環境を使用する際は注意してください。Squeakについては後編で説明します[3]。
Smalltalkのプログラムは全てオブジェクトとメッセージから構成します。Smalltalkで特徴的なのは、メッセージが3種類あることです。以下のソースを見てください。
#(・・・)を使用すると配列のオブジェクトを生成できます。配列はArrayクラスのインスタンスです。←は代入を表しています[4]。←が代入は分かりやすいですね。命令文が複数続く場合はピリオド"."を最後に付けます。ピリオド"."で終わるのは英語では自然なことなので、これもわかりやすいですね。arrayは変数を表していて、Javaのように型は指定できません。Smalltalkの変数はあらゆるオブジェクトを代入できます。2~4行目で配列のオブジェクトにメッセージを送り、それぞれ結果は5、3、#(2 4 6 8 10)になります。sizeメッセージは単項メッセージ、at:メッセージはキーワードメッセージと呼び、Javaに例えると単項メッセージは引数のないメソッド、キーワードメッセージは引数のあるメソッドになります。キーワードメッセージは:が付いているのが特徴です。最後の行の+も立派なメッセージで、2項メッセージと呼びます。Javaで配列と配列を足し合わせるとエラーになりますが、Smalltalkは演算子のようなものも全てメッセージなのでちゃんと動作します。
ブロックの使い方
次にブロックを見ていきます。ブロックとは後から実行可能な命令の固まりです。以下のソースを見てください。
[・・・]を使用するとブロックを作成できます。ブロックもちゃんとしたオブジェクトでBlockContextクラスのインスタンスです。ブロックを作成しただけだと、ブロック内の命令は実行されません。ブロックにvalueメッセージを送ると、ブロック内の命令を実行します。今回の場合、結果は7になります。ブロックには引数を渡すことも可能です。以下のソースを見てください。
先ほどと同じことを、引数を使用したブロックで行っています。ブロック内の|より前の部分で、受け取る引数を記述します。ブロックの実行は、value:メッセージで引数を指定します。
ブロックを使用することで、Smalltalkは条件分岐や繰り返し処理もオブジェクトとメッセージで実現します。以下のソースを見てください。
num変数にevenメッセージを送ると、偶数かどうかを判定し、trueまたはfalseのオブジェクトを返します。trueのオブジェクトはifTrue:メッセージ、falseのオブジェクトはifFalse:メッセージで指定されたブロックにvalueメッセージを送ります。今回の場合、結果は'偶数'になります。繰り返し処理は、数値のオブジェクトにto:do:メッセージを送ることで行います。今回の場合、do:メッセージで指定されたブロックに対してvalue:1~value:5のメッセージが送られ、sum変数は15になります。
便利なブロック
ブロックは、Arrayクラスなど、コレクションを走査するためのメッセージでとても上手に利用されています。先ほどのto:do:メッセージによる繰り返し処理は、Javaのfor文に似たような動作をしていて、配列から要素を取り出す記述が必要でしたが、配列のオブジェクトにdo:メッセージを送ると配列から要素を取り出す記述を省くことができます。以下のソースを見てください。
Smalltalkではこのように配列のオブジェクトにdo:メッセージを送り、配列の要素に順にアクセスすることができます。さらにもう1つ例を見てみましょう。
select:メッセージは指定されたブロックがtrueを返す要素だけを含む配列のオブジェクトを返します。この例では先ほどのdo:メッセージと組み合わせ、配列から偶数の要素のみを足し合わせた合計を計算していて、sum変数は6になります。ブロックの存在により、とてもシンプルに記述できていますね。
前編はSmalltalkの登場背景と特徴的な構文を紹介しました。Smalltalkはオブジェクトへのメッセージ送信が徹底されているため、日頃Javaを使用している人には新鮮に感じられると思います。後編はSmalltalkの大きな特徴の1つであるプログラミング環境についてお話します。