プログラミング言語/はじめに
初めに
[編集]プログラミング言語(programming language)は、コンピューターに特定のタスクを実行させるために使用される人工言語です。一般的にプログラミング言語とみなされるためには、計算機的に完全であること、すなわちチューリング完全であることが求められます。ただし、データベースクエリー言語やドメイン固有言語(DSL)など、計算完全でない言語もプログラミング言語と見なされるのが一般的です。
高水準プログラミング言語と低水準プログラミング言語
[編集]低水準プログラミング言語(low-level programming language)は、非常に基本的で、コンピューターの機械語(machine's native language)に近い言語です。これらは、ソフトウェアの構成言語(building block language)と考えることができます。アセンブリ言語は最も一般的な低水準言語であり、機械語(バイナリを構成する0と1)に変換するための翻訳がほとんど必要ありません。
一方、高水準プログラミング言語(high-level programming language)は、人間が理解しやすいコミュニケーションレベルに近い言語です。この方式では、プログラマーに代わってコンパイラがより多くの作業を行います。言語が私たちの日常会話に近ければ近いほど、より複雑な問題を抽象的に扱うことが容易になります。しかし、これが度を超すと、かえって問題が生じることがあります。言語があまりにも英語(あるいは他の自然言語)に似すぎると、冗長になり読むのに時間がかかるため、複雑なプログラムの理解が難しくなる場合があるのです。
機械語(machine code)は、コンピューターが直接理解できる言語です。機械語は2進数の列で構成されています。通常、直接プログラミングすることはほとんどありませんが、一般的なコンピューターで実行されるすべてのプログラムは、最終的に機械語に翻訳される必要があります。機械語は、コンピューターのアーキテクチャによって異なる場合があります。
アセンブリ言語(Assembly language)は、機械語をより人間に読みやすい形で表現したものです。マシン命令を2進数ではなく、ニーモニックで表現します。アセンブリ言語は、プログラムが自己修正しない限り、機械語と1対1の関係にあります。アセンブリプログラムをコンピューターで実行する前に、アセンブラと呼ばれるプログラムによって機械語に変換する必要があります。コンピューターの初期にはアセンブリ言語が広く使われていましたが、現在では主にプログラムの非常に時間のかかる部分、オペレーティングシステムの中核部分、スマートカードのチップのような非常に小さなコンピューターに限定して使われています。
機械語は第1世代プログラミング言語、アセンブリ言語は第2世代プログラミング言語と呼ばれています。算術式、ループ、関数など、プログラマーが機械語命令を直接扱わずに済むような構造を持つプログラミング言語を第3世代プログラミング言語といいます。
かつては、高水準・領域特化型プログラミング言語を第4世代言語、エキスパートシステムを第5世代言語と呼ぶことが多くありました。しかし、その後、Python、Haskell、Common Lispなど、非常に高度な汎用プログラミング言語が多数登場し、この区別は曖昧になっています。現在では、第5世代言語の代表例であったエキスパート・システムはほとんど使われていません。
コンピュータープログラムのコンパイルとインタープリテーション
[編集]コンピューターでプログラムを実行するには、まず機械語に翻訳(translate)し、翻訳された機械語を直接実行するか、またはインタープリタと呼ばれる別のプログラムによってシミュレーションする必要があります。
コンパイラは、ソースプログラミング言語(source programming language)と呼ばれるプログラミング言語を、デスティネーション言語(destination language)と呼ばれる別のプログラミング言語に翻訳するプログラムです。通常、ソースプログラミング言語は高水準言語であり、デスティネーション言語は機械語です。インタープリタは、ソースプログラミング言語をバイトコード(byte code)と呼ばれる中間形式にコンパイルしてから解釈することを要求する場合があります。バイトコードは、インタープリタを容易に記述できる、より低レベルの言語です。Javaでは、コンパイルは別工程で行われますが、PerlやPythonのように、コンパイルがインタープリタと一体で行われる場合もあります。Common Lispは例外的に、インタープリタとコンパイルの両方に対応しています。
型システム
[編集]型システム(type systems)には2つの軸があります。動的型付けか静的型付けか、そして強い型付けか弱い型付けかです。
強い型付け言語では、オブジェクトの型が一致しない場合、そのオブジェクトに対する操作を許容しません。Common Lisp、Q-base、Pythonなどがその例です。
一方、弱い型付け言語では、そのような操作が可能です。CやC++がその例です。
動的型付け言語は型と値を結びつけます(実行時に型が決まる)。静的型付け言語では型は変数に束縛されます(コンパイル時に型が決まる)。
メモリー管理
[編集]- 手動メモリー管理: プログラマーが直接、メモリの確保と解放を行う方式です。C言語やC++などがこれに該当し、高性能な制御が可能ですが、メモリリークなどのバグが発生しやすいという課題があります。
- ガベージコレクション(GC): プログラマーがメモリの解放を意識することなく、システムが不要になったメモリ領域を自動的に回収する方式です。Java、Python、Goなどが採用しており、開発効率と安全性が向上しますが、GCのオーバーヘッドが発生する可能性があります。