Luan - reactionary software by fschmidt

スクリプト: 21世紀の高レベルプログラミング

John K. Ousterhout


Tcl Developer Xchange
2593 Coast Ave.
Mountain View, CA 94043

(この記事はIEEE Computer誌、1998年3月号に掲載されています)
要約
PerlやTclのようなスクリプト言語は、CやJavaTMのようなシステムプログラミング言語とは非常に異なるスタイルのプログラミングを表しています。スクリプト言語はアプリケーションを「接着」するために設計されており、型なしのアプローチを使用して、システムプログラミング言語よりも高いレベルのプログラミングとより迅速なアプリケーション開発を実現します。コンピュータの速度の向上とアプリケーションのミックスの変化により、スクリプト言語は将来のアプリケーションにとってますます重要になっています。
キーワード: コンポーネントフレームワーク、オブジェクト指向プログラミング、スクリプト、強い型付け、システムプログラミング。

1 はじめに

過去15年間、人々がコンピュータプログラムを書く方法に根本的な変化が起こっています。この変化は、CやC++のようなシステムプログラミング言語から、PerlやTclのようなスクリプト言語への移行です。多くの人々がこの変化に参加していますが、それが起こっていることに気づいている人は少なく、なぜそれが起こっているのかを知っている人はさらに少ないです。この記事は、スクリプト言語が次の世紀の多くのプログラミングタスクをシステムプログラミング言語よりも優れた方法で処理する理由を説明する意見記事です。

スクリプト言語はシステムプログラミング言語とは異なるタスクのために設計されており、これが言語の根本的な違いをもたらします。システムプログラミング言語は、メモリのワードのような最も原始的なコンピュータ要素からデータ構造とアルゴリズムをゼロから構築するために設計されています。対照的に、スクリプト言語は接着のために設計されており、強力なコンポーネントのセットの存在を前提としており、主にコンポーネントを接続するために意図されています。システムプログラミング言語は複雑さを管理するために強い型付けがされていますが、スクリプト言語はコンポーネント間の接続を簡素化し、迅速なアプリケーション開発を提供するために型なしです。

スクリプト言語とシステムプログラミング言語は補完的であり、1960年代以降のほとんどの主要なコンピューティングプラットフォームは両方の種類の言語を提供しています。言語は通常、コンポーネントフレームワークで一緒に使用され、コンポーネントはシステムプログラミング言語で作成され、スクリプト言語で接着されます。しかし、最近のいくつかのトレンド、たとえばより高速なマシン、より良いスクリプト言語、グラフィカルユーザーインターフェースとコンポーネントアーキテクチャの重要性の増加、インターネットの成長などが、スクリプト言語の適用性を大幅に高めています。これらのトレンドは今後10年間続き、ますます多くの新しいアプリケーションが完全にスクリプト言語で書かれ、システムプログラミング言語は主にコンポーネントの作成に使用されるようになります。

2 システムプログラミング言語

スクリプト言語とシステムプログラミング言語の違いを理解するためには、システムプログラミング言語がどのように進化したかを理解することが重要です。システムプログラミング言語はアセンブリ言語の代替として導入されました。アセンブリ言語では、マシンのほぼすべての側面がプログラムに反映されます。各ステートメントは単一のマシン命令を表し、プログラマはレジスタ割り当てや手続き呼び出しシーケンスなどの低レベルの詳細を扱わなければなりません。その結果、アセンブリ言語で大規模なプログラムを書くことは難しく、維持することも困難です。

1950年代後半には、Lisp、Fortran、Algolのような高レベル言語が登場し始めました。これらの言語では、ステートメントはもはやマシン命令に正確に対応しておらず、コンパイラがソースプログラムの各ステートメントをバイナリ命令のシーケンスに変換します。時間が経つにつれて、AlgolからPL/1、Pascal、C、C++、Javaのようなシステムプログラミング言語が進化しました。システムプログラミング言語はアセンブリ言語よりも効率が悪いですが、アプリケーションをはるかに迅速に開発することができます。その結果、大規模なアプリケーションの開発においてアセンブリ言語をほぼ完全に置き換えました。

システムプログラミング言語はアセンブリ言語と2つの点で異なります: それらはより高レベルであり、強い型付けがされています。「高レベル」という用語は、多くの詳細が自動的に処理されることを意味し、プログラマが同じ作業を行うために少ないコードを書くことができることを意味します。たとえば:

平均して、システムプログラミング言語の各コード行は約5つのマシン命令に変換されますが、アセンブリ言語では1行あたり1命令です(5人の異なる人によって書かれた8つのCファイルの非公式な分析では、比率は約3から7命令/行の範囲でした[7]; 多数の言語の研究では、Capers Jonesは、特定のタスクに対して、アセンブリ言語はシステムプログラミング言語の約3-6倍のコード行を必要とすることを発見しました[3])。プログラマは言語に関係なく年間でほぼ同じ数のコード行を書くことができるため[1]、システムプログラミング言語はアセンブリ言語よりもはるかに迅速にアプリケーションを書くことができます。

アセンブリ言語とシステムプログラミング言語の2番目の違いは型付けです。私は「型付け」という用語を、情報の意味がその使用の前にどの程度指定されているかを指すために使用します。強い型付けの言語では、プログラマは各情報がどのように使用されるかを宣言し、言語は情報が他の方法で使用されるのを防ぎます。弱い型付けの言語では、情報がどのように使用されるかに関するa prioriの制限はありません: 情報の意味は、初期の約束ではなく、使用方法によってのみ決定されます。1

現代のコンピュータは基本的に型なしです: メモリ内の任意のワードは、整数、浮動小数点数、ポインタ、命令など、任意の種類の値を保持できます。値の意味は使用方法によって決定されます: プログラムカウンタがメモリのワードを指している場合、それは命令として扱われます; ワードが整数加算命令によって参照される場合、それは整数として扱われます; など。同じワードは異なる時に異なる方法で使用されることがあります。

対照的に、今日のシステムプログラミング言語は強い型付けがされています。 たとえば:

型付けにはいくつかの利点があります。まず、大規模なプログラムを管理しやすくするために、物事がどのように使用されるかを明確にし、異なる扱いを必要とするものを区別します。第二に、コンパイラは型情報を使用して、浮動小数点値をポインタとして使用しようとする試みなど、特定の種類のエラーを検出できます。第三に、型付けはコンパイラが特殊なコードを生成することを可能にすることによってパフォーマンスを向上させます。たとえば、コンパイラが変数が常に整数値を保持することを知っている場合、変数を操作するための整数命令を生成できます; コンパイラが変数の型を知らない場合、実行時に変数の型をチェックするための追加の命令を生成しなければなりません。

要約すると、システムプログラミング言語はアセンブリ言語と同じタスク、すなわちゼロからアプリケーションを作成するために設計されています。システムプログラミング言語はアセンブリ言語よりも高レベルで、はるかに強い型付けがされています。これにより、アプリケーションをより迅速に作成し、わずかなパフォーマンスの損失でより簡単に管理することができます。アセンブリ言語といくつかのシステムプログラミング言語のグラフィカルな比較については図 1を参照してください。

3 スクリプト言語

Perl[9]、Python[4]、Rexx[6]、Tcl[8]、Visual Basic、Unixシェルのようなスクリプト言語は、システムプログラミング言語とは非常に異なるスタイルのプログラミングを表しています。スクリプト言語は、他の言語で書かれた有用なコンポーネントのコレクションがすでに存在することを前提としています。スクリプト言語はゼロからアプリケーションを書くことを意図しておらず、主にコンポーネントをプラグインするために意図されています。たとえば、TclやVisual Basicは、画面上のユーザーインターフェイスコントロールのコレクションを配置するために使用でき、Unixシェルスクリプトはフィルタプログラムをパイプラインに組み立てるために使用されます。スクリプト言語はしばしばコンポーネントの機能を拡張するために使用されますが、複雑なアルゴリズムやデータ構造にはめったに使用されません; これらのような機能は通常コンポーネントによって提供されます。スクリプト言語はグルー言語またはシステム統合言語と呼ばれることがあります。

コンポーネントを接続するタスクを簡素化するために、スクリプト言語は型なしである傾向があります: すべてのものが同じように見え、同じように振る舞うため、互換性があります。たとえば、TclやVisual Basicでは、変数はある瞬間に文字列を保持し、次の瞬間には整数を保持することができます。コードとデータはしばしば互換性があり、プログラムが別のプログラムを書き、その場で実行することができます。スクリプト言語はしばしば文字列指向であり、これは多くの異なるものに対して一様な表現を提供します。

型なしの言語は、コンポーネントを接続するのをはるかに簡単にします。物事がどのように使用されるかに関するa prioriの制限はなく、すべてのコンポーネントと値は一様な方法で表現されます。したがって、任意のコンポーネントまたは値は任意の状況で使用できます; ある目的のために設計されたコンポーネントは、設計者が予見しなかった全く異なる目的のために使用されることがあります。たとえば、Unixシェルでは、すべてのフィルタプログラムは入力からバイトのストリームを読み取り、出力にバイトのストリングを書き込みます; 任意の2つのプログラムは、1つのプログラムの出力を他のプログラムの入力に接続することによって接続できます。次のシェルコマンドは、選択内の「スクリプト」という単語を含む行の数を数えるために3つのフィルタを積み重ねます:

select | grep scripting | wc selectプログラムは、ディスプレイ上で現在選択されているテキストを読み取り、それを出力に印刷します; grepプログラムは入力を読み取り、「スクリプト」を含む行を出力に印刷します; wcプログラムは入力の行数を数えます。これらのプログラムのそれぞれは、異なるタスクを実行するために他の多くの状況で使用できます。

システムプログラミング言語の強い型付けの性質は再利用を妨げます。型付けはプログラマにさまざまな互換性のないインターフェースを作成することを奨励します(「インターフェースは良い; より多くのインターフェースはより良い」)。各インターフェースは特定の型のオブジェクトを必要とし、コンパイラはインターフェースで他の型のオブジェクトを使用することを防ぎます。それが有用であっても。新しいオブジェクトを既存のインターフェースで使用するためには、オブジェクトの型とインターフェースが期待する型の間を変換するコードを書かなければなりません。これは、アプリケーションがバイナリ形式で配布される一般的な場合には不可能であるため、アプリケーションの一部またはすべてを再コンパイルする必要があります。

型なしの言語の利点を理解するために、次のTclコマンドを考えてみましょう:

button .b -text Hello! -font {Times 16} -command {puts hello} このコマンドは、16ポイントのTimesフォントでテキスト文字列を表示し、ユーザーがコントロールをクリックしたときに短いメッセージを印刷する新しいボタンコントロールを作成します。これは、単一のステートメントで6つの異なる種類のものを混ぜています: コマンド名(button)、ボタンコントロール(.b)、プロパティ名(-text-font-command)、単純な文字列(Hello!hello)、フォント名(Times 16)で、書体名(Times)とポイントサイズ(16)を含み、Tclスクリプト(puts hello)です。Tclはこれらのすべてを文字列で一様に表現します。この例では、プロパティは任意の順序で指定でき、指定されていないプロパティにはデフォルト値が与えられます; この例では20以上のプロパティが指定されていませんでした。

同じ例は、Javaで実装すると2つのメソッドで7行のコードが必要です。C++とMicrosoft Foundation Classesでは、3つの手続きで約25行のコードが必要です(これらの例のコードについては[7]を参照してください)。フォントを設定するだけでも、Microsoft Foundation Classesでは数行のコードが必要です:

CFont *fontPtr = new CFont();
fontPtr->CreateFont(16, 0, 0,0,700, 0, 0, 0, ANSI_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE, "Times New Roman");
buttonPtr->SetFont(fontPtr);
このコードの多くは強い型付けの結果です。ボタンのフォントを設定するためには、そのSetFontメソッドを呼び出す必要がありますが、このメソッドにはCFontオブジェクトへのポインタを渡す必要があります。これにより、新しいオブジェクトを宣言して初期化する必要があります。CFontオブジェクトを初期化するためには、そのCreateFontメソッドを呼び出す必要がありますが、CreateFontには14の異なる引数を指定する必要がある厳格なインターフェースがあります。Tclでは、フォントの本質的な特性(書体Times、サイズ16ポイント)は、宣言や変換なしで即座に使用できます。さらに、Tclはボタンの動作をボタンを作成するコマンドに直接含めることができますが、C++やJavaではそれを別に宣言されたメソッドに配置する必要があります。

(実際には、このような些細な例は、基礎となる言語の複雑さを隠すグラフィカルな開発環境で処理される可能性があります: ユーザーはフォームにプロパティ値を入力し、開発環境はコードを出力します。しかし、プロパティ値の条件付き割り当てやプログラムによって生成されたインターフェースなどのより複雑な状況では、開発者は基礎となる言語でコードを書く必要があります。)

スクリプト言語の型なしの性質がエラーを見逃す可能性があるように思えるかもしれませんが、実際にはスクリプト言語はシステムプログラミング言語と同じくらい安全です。たとえば、上記のボタンの例で指定されたフォントサイズがxyzのような非整数文字列である場合、エラーが発生します。違いは、スクリプト言語は値が使用される最後の瞬間にエラーチェックを行うことです。強い型付けはコンパイル時にエラーを検出することを可能にし、実行時のチェックのコストを回避します。しかし、この効率のために支払う代償は、情報の使用方法に対する制限です: これにより、より多くのコードと柔軟性の低いプログラムが生まれます。

スクリプト言語とシステムプログラミング言語のもう一つの重要な違いは、スクリプト言語は通常インタープリタであり、システムプログラミング言語は通常コンパイラであることです。インタープリタ言語は、コンパイル時間を排除することによって開発中の迅速なターンアラウンドを提供します。インタープリタはまた、ユーザーが実行時にアプリケーションをプログラムすることを可能にすることによって、アプリケーションをより柔軟にします。たとえば、多くの集積回路の合成および解析ツールにはTclインタープリタが含まれており、プログラムのユーザーはTclスクリプトを書いて設計を指定し、ツールの操作を制御します。インタープリタはまた、コードをその場で生成することによって強力な効果を達成することを可能にします。たとえば、TclベースのWebブラウザは、WebページのHTMLをいくつかの正規表現の置換を使用してTclスクリプトに変換することによってWebページを解析できます。それからTclスクリプトを実行して画面にページをレンダリングします。

スクリプト言語はシステムプログラミング言語よりも効率が悪いです。これは、コンパイラの代わりにインタープリタを使用するためだけでなく、基本コンポーネントが基礎となるハードウェアへの効率的なマッピングよりも、パワーと使いやすさのために選ばれているためです。たとえば、スクリプト言語は、システムプログラミング言語が単一のマシンワードに収まるバイナリ値を使用する状況で、可変長文字列を使用することがよくあります。また、スクリプト言語は、システムプログラミング言語がインデックス付き配列を使用する状況で、ハッシュテーブルを使用することがよくあります。

幸いなことに、スクリプト言語のパフォーマンスは通常大きな問題ではありません。スクリプト言語のアプリケーションは通常、システムプログラミング言語のアプリケーションよりも小さく、スクリプトアプリケーションのパフォーマンスは、通常システムプログラミング言語で実装されるコンポーネントのパフォーマンスによって支配される傾向があります。

スクリプト言語はシステムプログラミング言語よりも高レベルであり、平均して単一のステートメントがより多くの作業を行います。スクリプト言語の典型的なステートメントは数百または数千のマシン命令を実行しますが、システムプログラミング言語の典型的なステートメントは約5つのマシン命令を実行します(図 1を参照)。この違いの一部は、スクリプト言語がインタープリタを使用しているためであり、システムプログラミング言語のコンパイル済みコードよりも効率が悪いです。しかし、この違いの多くは、スクリプト言語の基本操作がより大きな機能を持っているためです。たとえば、Perlでは、正規表現の置換を呼び出すのは整数の加算を呼び出すのと同じくらい簡単です。Tclでは、変数にトレースを関連付けることができ、変数を設定すると副作用が発生します。たとえば、トレースは変数の値を画面上で継続的に更新するために使用されるかもしれません。

上記の特徴により、スクリプト言語は接着指向のアプリケーションの非常に迅速な開発を可能にします。表 1は、この主張を支持する逸話的な証拠を提供します。それは、システムプログラミング言語で実装され、その後スクリプト言語で再実装された、またはその逆のいくつかのアプリケーションを説明しています。

すべての場合において、スクリプトバージョンはシステムプログラミングバージョンよりも少ないコードと開発時間を必要としました; 違いは2倍から60倍まで変動しました。スクリプト言語は、最初の実装に使用された場合、あまり利益をもたらしませんでした; これは、再実装が最初の実装の経験から大いに利益を得ることを示唆しており、スクリプトとシステムプログラミングの真の違いは、表の極端なポイントよりも5-10倍のようなものです。スクリプトの利点はアプリケーションによっても異なります。表の最後の例では、アプリケーションのGUI部分は接着指向ですが、シミュレータ部分はそうではありません; これは、アプリケーションが他のアプリケーションよりもスクリプトからの利益が少なかった理由を説明するかもしれません。

要約すると、スクリプト言語はアプリケーションを接着するために設計されています。それらはアセンブリまたはシステムプログラミング言語よりも高いレベルのプログラミングを提供し、システムプログラミング言語よりもはるかに弱い型付けを提供し、インタープリタ開発環境を提供します。スクリプト言語は、開発速度を向上させるために実行速度を犠牲にします。

4 異なるタスクに異なるツール

スクリプト言語はシステムプログラミング言語の代替ではありませんし、その逆もありません。それぞれが異なるタスクのセットに適しています。接着とシステム統合のために、スクリプト言語を使用するとアプリケーションを5-10倍速く開発できます; システムプログラミング言語は、ピースを接続するために大量のボイラープレートと変換コードを必要としますが、これはスクリプト言語で直接行うことができます。複雑なアルゴリズムとデータ構造の場合、システムプログラミング言語の強い型付けはプログラムを管理しやすくします。実行速度が重要な場合、システムプログラミング言語はスクリプト言語よりも10-20倍速く実行できることがよくあります。

特定のタスクにスクリプト言語またはシステムプログラミング言語を使用するかどうかを決定する際には、次の質問を考慮してください:

これらの質問に「はい」と答えることは、スクリプト言語がアプリケーションに適していることを示唆しています。一方、次の質問に「はい」と答えることは、アプリケーションがシステムプログラミング言語に適していることを示唆しています:

過去30年間の主要なコンピューティングプラットフォームのほとんどは、システムプログラミングと言語とスクリプト言語の両方を提供しています。たとえば、最初のスクリプト言語の1つは、OS/360でジョブステップをシーケンスするために使用されたJCL(ジョブ制御言語)でした。個々のジョブステップは、その日のシステムプログラミング言語であるPL/1、Fortran、またはアセンブラ言語で書かれていました。1980年代のUnixマシンでは、Cがシステムプログラミングに使用され、shcshのようなシェルプログラムがスクリプトに使用されました。1990年代のPCの世界では、CとC++がシステムプログラミングに使用され、Visual Basicがスクリプトに使用されました。現在形成されつつあるインターネットの世界では、Javaがシステムプログラミングに使用され、JavaScript、Perl、Tclのような言語がスクリプトに使用されています。

スクリプトとシステムプログラミングは共生的です。両方を使用すると、非常に強力なプログラミング環境が生まれます: システムプログラミング言語はエキサイティングなコンポーネントを作成するために使用され、その後、スクリプト言語を使用してコンポーネントを組み立てることができます。たとえば、Visual Basicの魅力の多くは、システムプログラマがCでActiveXコンポーネントを書くことができ、あまり洗練されていないプログラマがVisual Basicアプリケーションでコンポーネントを使用できることです。Unixでは、Cで書かれたアプリケーションを呼び出すシェルスクリプトを書くのは簡単です。Tclの人気の理由の1つは、新しいコマンドを実装するCコードを書くことによって言語を拡張する能力です。

5 スクリプトは上昇中

スクリプト言語は長い間存在していましたが、近年、いくつかの要因がその重要性を高めています。最も重要な要因は、アプリケーションのミックスが接着アプリケーションに向かってシフトしていることです。このシフトの3つの例は、グラフィカルユーザーインターフェース、インターネット、コンポーネントフレームワークです。

グラフィカルユーザーインターフェース(GUI)は1980年代初頭に登場し、1980年代の終わりまでに広まりました; GUIは多くのプログラミングプロジェクトで総労力の半分以上を占めています。GUIは基本的に接着アプリケーションです: 目標は新しい機能を作成することではなく、グラフィカルコントロールのコレクションとアプリケーションの内部機能の間に接続を作成することです。システムプログラミング言語に基づくGUIのための迅速な開発環境を私は知りません。環境がWindows、Macintosh Toolbox、またはUnix Motifであるかどうかにかかわらず、CやC++のような言語に基づくGUIツールキットは、学習が難しく、使用が不便で、生成される結果が柔軟性に欠けることが証明されています。これらのシステムのいくつかは、画面レイアウトを設計するための非常に良いグラフィカルツールを持っており、基礎となる言語を隠していますが、デザイナーがコードを書く必要があるとすぐに、たとえばインターフェース要素の動作を提供するために、物事は難しくなります。最高の迅速な開発GUI環境はすべてスクリプト言語に基づいています: Visual Basic、HyperCard、Tcl/Tk。したがって、GUIの重要性が増すにつれて、スクリプト言語の人気が高まっています。

インターネットの成長もスクリプト言語を普及させました。インターネットは接着ツールに過ぎません。それは新しい計算やデータを作成するものではなく、既存の多くのものを簡単にアクセス可能にするだけです。ほとんどのインターネットプログラミングタスクに理想的な言語は、すべての接続されたコンポーネントが一緒に動作できるようにする言語、すなわちスクリプト言語です。たとえば、PerlはCGIスクリプトを書くために人気があり、JavaScriptはWebページでのスクリプトに人気があります。

スクリプト指向のアプリケーションの3番目の例は、ActiveX、OpenDoc、JavaBeansのようなコンポーネントフレームワークです。システムプログラミング言語はコンポーネントの作成に適していますが、コンポーネントをアプリケーションに組み立てるタスクはスクリプトに適しています。コンポーネントを操作するための良いスクリプト言語がなければ、コンポーネントフレームワークの多くの力が失われます。これが、Visual Basicが便利なスクリプトツールを提供するPCでコンポーネントフレームワークが他のプラットフォーム(Unix/CORBAなど)よりも成功している理由の一部を説明しているかもしれません。

スクリプト言語の人気が高まっているもう一つの理由は、スクリプト技術の改善です。TclやPerlのような現代のスクリプト言語は、JCLのような初期のスクリプト言語とは大きく異なります。たとえば、JCLは基本的な反復さえ提供しておらず、初期のUnixシェルは手続きをサポートしていませんでした。スクリプト技術は今日でも比較的未熟です。たとえば、Visual Basicは本当にスクリプト言語ではありません; それはもともと単純なシステムプログラミング言語として実装され、その後スクリプトにより適するように変更されました。将来のスクリプト言語は、今日利用可能なものよりもさらに良くなるでしょう。

スクリプト技術はまた、コンピュータハードウェアの速度の絶え間ない向上からも恩恵を受けています。かつては、ある程度の複雑さを持つアプリケーションで許容できるパフォーマンスを得る唯一の方法は、システムプログラミング言語を使用することでした。場合によっては、システムプログラミング言語でさえ効率的ではなく、アプリケーションはアセンブラで書かれなければなりませんでした。しかし、今日のマシンは1980年のマシンよりも100-500倍速く、18ヶ月ごとにパフォーマンスが倍増し続けています。今日、多くのアプリケーションはインタープリタ言語で実装され、依然として優れたパフォーマンスを持つことができます; たとえば、Tclスクリプトは数千のオブジェクトを持つコレクションを操作し、依然として良好なインタラクティブ応答を提供できます。コンピュータが速くなるにつれて、スクリプトはより大きなアプリケーションにとって魅力的になります。

スクリプト言語の使用が増えている最後の理由は、プログラマコミュニティの変化です。20年前、ほとんどのプログラマは大規模なプロジェクトに取り組む洗練されたプログラマでした。その時代のプログラマは、言語とそのプログラミング環境を習得するのに数ヶ月を費やすことを期待しており、システムプログラミング言語はそのようなプログラマのために設計されていました。しかし、パーソナルコンピュータの到来以来、ますます多くのカジュアルプログラマがプログラマコミュニティに加わりました。これらの人々にとって、プログラミングは彼らの主な仕事の機能ではありません; それは彼らの主な仕事を助けるために時折使用するツールです。カジュアルプログラミングの例は、単純なデータベースクエリやスプレッドシートのマクロです。カジュアルプログラマは、システムプログラミング言語を学ぶのに数ヶ月を費やすことを望んでいませんが、スクリプト言語について数時間で十分に学び、有用なプログラムを書くことができることがよくあります。スクリプト言語は、システムプログラミング言語よりも簡単な構文を持ち、オブジェクトやスレッドのような複雑な機能を省略しているため、学びやすいです。たとえば、Visual BasicとVisual C++を比較してください; 少数のカジュアルプログラマがVisual C++を使用しようとしますが、多くの人がVisual Basicで有用なアプリケーションを構築することができました。

今日でも、スクリプト言語で書かれたアプリケーションの数は、システムプログラミング言語で書かれたアプリケーションの数よりもはるかに多いです。Unixシステムでは、Cプログラムよりも多くのシェルスクリプトがあり、Windowsでは、CまたはC++よりも多くのVisual Basicプログラマとアプリケーションがあります。もちろん、最も大きく、最も広く使用されているアプリケーションのほとんどはシステムプログラミング言語で書かれているため、総コード行数やインストールされたコピー数に基づく比較は依然としてシステムプログラミング言語を支持するかもしれません。それにもかかわらず、スクリプト言語はすでにアプリケーション開発において主要な力であり、将来的にはその市場シェアが増加するでしょう。

6 オブジェクトの役割

スクリプト言語は、プログラミング言語とソフトウェア工学の専門家によってほとんど見過ごされています。代わりに、彼らはC++やJavaのようなオブジェクト指向のシステムプログラミング言語に注目しています。オブジェクト指向プログラミングは、プログラミング言語の進化における次の主要なステップを表していると広く信じられています。強い型付けや継承のようなオブジェクト指向の特徴は、開発時間を短縮し、ソフトウェアの再利用を増やし、スクリプト言語によって解決される問題を含む多くの問題を解決すると主張されることがよくあります。

オブジェクト指向プログラミングは実際にどれだけの利益をもたらしましたか? 残念ながら、この質問に決定的に答えるための十分な定量的データを見たことがありません。私の意見では、オブジェクトはわずかな利益しか提供しません: 生産性の20-30%の改善かもしれませんが、2倍の要因ではなく、ましてや10倍の要因ではありません。C++は今や愛されるのと同じくらい嫌われているようであり、いくつかの言語の専門家はオブジェクト指向プログラミングに反対する声を上げ始めています[2]。このセクションの残りは、オブジェクトがスクリプトが行うような劇的な方法で生産性を向上させない理由を説明し、スクリプト言語でオブジェクト指向プログラミングの利点を達成できることを主張します。

オブジェクト指向プログラミングが生産性の大幅な向上を提供しない理由は、それがプログラミングのレベルを上げたり、再利用を促進したりしないからです。C++のようなオブジェクト指向言語では、プログラマは依然として詳細に記述し操作しなければならない小さな基本単位で作業します。原則として、強力なライブラリパッケージが開発され、これらのライブラリが広く使用されれば、プログラミングのレベルを上げることができます。しかし、そのようなライブラリはあまり存在していません。ほとんどのオブジェクト指向言語の強い型付けは、再利用が難しい狭く定義されたパッケージを奨励します。各パッケージは特定の型のオブジェクトを必要とし、2つのパッケージが一緒に動作するためには、パッケージが要求する型の間を変換するコードを書かなければなりません。

オブジェクト指向言語のもう一つの問題は、継承に重点を置いていることです。あるクラスが別のクラスのために書かれたコードを借りる実装継承は、ソフトウェアを管理し再利用するのを難しくする悪い考えです。それはクラスの実装を結びつけ、どちらのクラスも他のクラスなしでは理解できないようにします: サブクラスは、スーパークラスで実装されたメソッドがどのように実装されているかを知らずに理解できず、スーパークラスはサブクラスでメソッドがどのように継承されているかを知らずに理解できません。複雑なクラス階層では、個々のクラスは階層内のすべての他のクラスを理解せずに理解できません。さらに悪いことに、クラスは再利用のためにその階層から分離することができません。多重継承はこれらの問題をさらに悪化させます。実装継承は、gotoステートメントが過剰に使用されると観察されるのと同じ絡み合いと脆弱性を引き起こします。その結果、オブジェクト指向システムはしばしば複雑さと再利用の欠如に苦しみます。

一方、スクリプト言語は実際に大幅なソフトウェア再利用を生み出しました。それらは、興味深いコンポーネントがシステムプログラミング言語で構築され、その後スクリプト言語を使用してアプリケーションに接着されるモデルを使用しています。この労働の分割は、再利用性のための自然なフレームワークを提供します。コンポーネントは再利用可能に設計されており、コンポーネントとスクリプトの間には明確に定義されたインターフェースがあり、コンポーネントを簡単に使用できます。たとえば、Tclでは、コンポーネントはCで実装されたカスタムコマンドであり、組み込みコマンドと同じように見えるため、Tclスクリプトで簡単に呼び出すことができます。Visual Basicでは、コンポーネントはActiveX拡張であり、パレットからフォームにドラッグすることで使用できます。

それにもかかわらず、オブジェクト指向プログラミングは少なくとも2つの有用な機能を提供します。最初のものはカプセル化です: オブジェクトはデータとコードを組み合わせて実装の詳細を隠します。これにより、大規模なシステムを管理しやすくなります。2番目の有用な機能はインターフェース継承です。これは、異なる実装を持っていても同じメソッドとAPIを提供するクラスを指します。これにより、クラスが交換可能になり、再利用が促進されます。

幸いなことに、オブジェクトの利点はシステムプログラミング言語と同様にスクリプト言語でも達成できます。ほとんどすべてのスクリプト言語はオブジェクト指向プログラミングをサポートしています。たとえば、Pythonはオブジェクト指向のスクリプト言語であり、Perlバージョン5はオブジェクトをサポートしており、Object RexxはRexxのオブジェクト指向バージョンであり、Incr TclはTclのオブジェクト指向拡張です。1つの違いは、スクリプト言語のオブジェクトは型なしである傾向があり、システムプログラミング言語のオブジェクトは強い型付けがされている傾向があることです。

7 他の言語

この記事は、すべてのプログラミング言語の完全な特徴付けを意図したものではありません。プログラミング言語には、型付けの強さやプログラミングのレベル以外にも多くの属性があり、システムプログラミング言語やスクリプト言語としてきれいに特徴付けることができない多くの興味深い言語があります。たとえば、Lispファミリーの言語は、スクリプトとシステムプログラミングの間のどこかに位置し、それぞれの属性のいくつかを持っています。Lispは、スクリプト言語で一般的になっている解釈と動的型付けの概念を先駆けており、スクリプトとシステムプログラミング言語の両方で使用されている自動ストレージ管理と統合開発環境も先駆けています。

8 結論

スクリプト言語は、システムプログラミング言語とは異なるトレードオフのセットを表しています。それらは、システムプログラミング言語に比べて実行速度と型付けの強さを犠牲にしますが、プログラマの生産性とソフトウェアの再利用を大幅に向上させます。このトレードオフは、コンピュータがプログラマに比べてますます速く安くなるにつれて、ますます意味を持ちます。システムプログラミング言語は、データ構造とアルゴリズムの複雑さがあるコンポーネントの構築に適しており、スクリプト言語は接着アプリケーションに適しており、複雑さは接続にあります。接着タスクはますます普及しているため、スクリプトは次の世紀において今日よりもさらに重要なプログラミングパラダイムになるでしょう。

この記事がコンピューティングコミュニティに3つの方法で影響を与えることを望んでいます:

9 謝辞

この記事は、Joel Bartlett、Bill Eldridge、Jeffrey Haemer、Mark Harrison、Paul McJones、David Patterson、Stephen Uhler、Hank Walker、Chris Wright、IEEE Computerの審査員、そしてこの記事の初期の草稿に関する熱いネットニュースディスカッションに参加した他の何十人もの人々のコメントから恩恵を受けました。Colin Stevensはボタンの例のMFCバージョンを書き、Stephen UhlerはJavaバージョンを書きました。

10 参考文献

[1] B. Boehm, Software Engineering Economics, Prentice-Hall, ISBN 0-138-22122-7, 1981.

[2] S. Johnson, Objecting To Objects, Invited Talk, USENIX Technical Conference, San Francisco, CA, January 1994.

[3] C. Jones, "Programming Languages Table, Release 8.2", March 1996, http://www.spr.com/library/0langtbl.htm.

[4] M. Lutz, Programming Python, O'Reilly, ISBN 1-56592-197-6, 1996.

[5] Netscape Inc., "JavaScript in Navigator 3.0", http://home.netscape.com/eng/mozilla/3.0/handbook/javascript/atlas.html#taint_dg.

[6] R. O'Hara and D. Gomberg, Modern Programming Using REXX, Prentice Hall, ISBN 0-13-597329-5, 1988.

[7] J. Ousterhout, Additional Information for Scripting White Paper, http://www.ajubasolutions.com/people/john.ousterhout/scriptextra.html.

[8] J. Ousterhout, Tcl and the Tk Toolkit, Addison-Wesley, ISBN 0-201-63337-X, 1994.

[9] L. Wall, T. Christiansen, and R. Schwartz, Programming Perl, Second Edition, O'Reilly and Associates, ISBN 1-56592-149-6, 1996.

SunとJavaは、米国および他の国におけるSun Microsystems, Inc.の商標または登録商標です。



1 より正確な特徴付けは、私が「強い型付け」と言うところで「静的型付け」という用語を使用し、弱い型付けまたは型なしと説明するスクリプト言語に対して「動的型付けと自動変換」を使用するでしょう。私は「型付け」という用語を、データの使用が事前にどの程度制限されているかを説明する一般的な意味で使用しています。

Tcl DeveloperXChange
最終更新日: 2000年8月8日

ここからコピーされました。 scripting.pdfも参照してください。