Rubyist のための他言語探訪 【第 4 回】 Tcl

著者:まつもとゆきひろ

編集:なかむら

はじめに

「Rubyist のための他言語探訪」は、Ruby 作者まつもとゆきひろが、Ruby と関係があったりなかったりする他の言語を紹介していく連載です。 他の言語を知ることによって、視野が広がると同時に、逆に Ruby への理解も深まることでしょう。

今回は、Tcl を紹介します。

Tcl とは

先月の Io に引き続き、今月もシンプルな言語を取り上げましょう。今月は Tcl (Tool Command Language) です。「てぃくる」と発音します。Tcl は 1988 年頃、University of California at Berkeley で誕生しました。作者は John Ousterhout です。彼はもともと Tcl を CAD ソフトウェアの拡張用言語として開発しました。Tcl の Tool Command Language という名前は、オリジナルの目的を反映しています。その目的のため Tcl は

  • 単純な文法
  • 単純な実装
  • 組み込みを意識した API

を提供していました。Tcl がどのような言語であるかについては、後で紹介することにしましょう。

Tk とは

Tcl が組込み用言語で留まっていればこれほど知られることはなかったでしょう。Tcl が広く知られるようになったのは、Tcl から使えることができたライブラリ Tk (Tool Kit) のおかげです。これは Tcl から簡単に GUI を記述できるようなライブラリです。このライブラリは

  • 各種 OS 上で動作する移植性
  • Xlib、Xt などよりもはるかに高機能な GUI 部品
  • インタプリタ言語による生産性

のおかげで人気となり、一時は GUI といえば Tcl/Tk という時代がありました (90 年代前半)。各種言語も Tk へのインタフェースを提供しました。残念なことに Tk は Tcl と非常に強く結合していたので引きはがすことは不可能でした (試みはいくつも行われたのですが)。ですから、それらのインタフェースは必然的に Tcl も取り込むことになりました。Ruby をはじめとする多くの言語は Tk バインディングを提供していますが、今でもその影でひっそり Tcl インタプリタが動作しているのです。

Tcl 言語

さて、この連載が取り扱うのは言語のことですから、まず文法について紹介しましょう。Tcl は徹底的に仕様が小さな言語です。なにより取り扱うデータ型がひとつしかありません。Tcl ではあらゆるデータは文字列です。数値とか構造体とかそのようなものはなく、すべて文字列で表現します。Tcl では以下のものはすべて文字列です。

 foo
 foo bar
 "foo bar"
 {foo bar baz {qux quux}}

最初の行は “foo” という文字列、次の行は “foo” という文字列と “bar” というふたつの文字列 (空白が区切りになる)、その次の行は “foo bar” という文字列 (空白を含むときにはクォーテーションマークで囲む) です。さらに、ブレースはネストを許す引用記号ですから、最後の文字列は “foo bar baz {qux quux}” という内容の文字列になります。

文字列が Tcl のプログラムとして解釈される場合には、各行ごとに、最初の文字列がコマンド名、残りの文字列が引数と解釈されます。つまり、

 puts "hello world"

は puts というコマンドを “hello world” という文字列を引数として呼び出していることになります。クォートおよびブレースは改行より優先されますから、

 foo {
   1
 }

は、foo というコマンドをブレースで囲まれた文字列を引数として呼び出していることになります。

文字列表現とコマンド呼び出し以外には、Tcl の組み込みの文法はあと二つしかありません。ひとつはブラケット ([]) であり、これはブラケットの中身を評価した文字列をその値とします。もうひとつは $ で直後に指定した名前を持つ変数の値を取り出します。これで Tcl の文法は全てです。それ以外のものはすべてコマンドで実装されます。

たとえば変数の設定 (代入) は set コマンドで行います。

 set a "foo"

値の取り出しは先ほど説明した $ を用いても構わないのですが、set コマンドを 1 引数で呼び出すとその変数の値を取り出します。

 set a

「$変数」も結局はこれの別名に過ぎません。

制御構造もコマンドです。

 if [some command] then {
   puts "true"
 } else {
   puts "false"
 }

これは組み込みの文法ではなく、if という名前のコマンドです。第 1 引数がブラケットで括ってあることに注意してください。then や else も予約語ではなく、単なる文字列です。Tcl の if は「賢い」ので引数に与えられた then や else という文字列を読み飛ばしてくれます。Tcl では「呼出元のコンテキストで文字列を評価する」機能がありますから、自分で制御構造を定義することも簡単にできます。

では、数値などはどうするかというと、数字として取り扱い、計算が必要になった時点で数値化します。結果ももちろん計算結果を数字として用いるわけです。expr コマンドが与えられた文字列を数式として解釈してくれます。

 set a 10
 set b 2
 if [expr $a+$b < 20] then {puts "<20\n"}

Tcl の文法といえるものはたったこれだけです。ある意味最小の文法の言語のひとつでしょう。後は数多く定義されているコマンドを使いこなすだけです。もっともこの数が半端じゃなかったりするんですが。

すべては文字列という Tcl のデータモデルは、とても高速に実行できそうにないですが、シンプルさという意味では最強かもしれません。さすがにこのままでは遅いと思ったのか、新しいバージョンの Tcl (確か 8.0 以降) では数値として扱われた文字列には数値をキャッシュしたりしています。

Tcl の文法は究極にシンプルではあるものの記述力に劣るわけではありません。数式を必要とする度に expr と書く必要があるのは面倒とかそういうことは置いておくとして。たとえば、Tk ではコマンドを動的に生成してオブジェクト指向的プログラミングを実現しています。

 set $obj [Object new]
 $obj method arg1 arg2

これは $obj に格納されている名前がコマンドで、そのコマンドが第 1 引数でメソッドを (手動で) ディスパッチしているのです。これを自動化する [incr Tcl] というオブジェクト指向ライブラリも存在しています。[incr Tcl] とはつまり Tcl の文法で 1 増加させるということで、C++ と同じ発想の命名方法です。

それからの Tcl

1990 年代前半の Tcl 絶頂を受けて、Tcl の作者 John Ousterhout は 1994 年に Sun に移籍し、しばらくの間、Sun がスポンサーとなって Tcl の開発が行われました。その後、Tcl 開発チームは 1998 年に Scriptics という企業として Sun からスピンアウトしました。商用 Tcl 処理系である TclPro を提供したことが記憶に残っています。

しかし、Scriptics は 2000 年 5 月に Ajuba Solutions と名前を変え、Tcl をベースにした XML ソリューションにフォーカスすることになりました。その年の 10 月、Ajuba Solutions は Interwoven に買収されてしまいました。XML 技術だけを欲してオープンソースにまったく関心のない Interwoven は Tcl のサポートを止めてしまいました。今では他の多くのオープンソースソフトウェアと同様、Tcl Core Team という集団体制で開発が行われています。

まとめ

最近、あまり Tcl の話題を聞かなくなり、失礼ながら消え去ったかなと思っていたのですが、ホームページ (Tcl Developer Site) を調べると最新版 (8.4.11) は 2005 年 7 月 28 日にリリースされています (Tcl/Tk 8.4) し、つい先頃、12th Annual Tcl/Tk Conference もオレゴン州ポートランドで開催されています (Tcl ‘2005)。一度広まった言語はしぶとく生き残り続けるようです (Ruby もそうだといいなあ)。超シンプル言語 Tcl のこれからを見守りたいと思います。

参考文献

Tcl Developer Site
Tcl 公式サイト。Tcl 言語についての概要、チュートリアル (Tcl Tutorial)、マニュアル類 (Tcl/Tk Manual Pages) などがあります。全部英語です。
もっとTcl/Tk
日本語での Tcl/Tk の情報が豊富です。

著者について

matz_in_suit.jpgまつもとゆきひろは自他ともに認める日本を代表する言語オタクです。 言語好きが昂じて自分の言語を設計してしまった大馬鹿者です。 が、オタクとかハッカーとか呼ばれる人種はみんな多かれ少なかれそんなものじゃないでしょうか。

Rubyist のための他言語探訪 連載一覧