Luan - reactionary software by fschmidt

スクリプティング: 21世紀のための高レベルプログラミング

ジョン・K・オースターハウト


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ブラウザは、ページの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も参照してください。