高水準言語

記述の抽象度が高いプログラミング言語 From Wikipedia, the free encyclopedia

高水準言語(こうすいじゅんげんご、high-level programming language、高級言語とも)とは、機械語アセンブリ言語などの低水準言語に対して、コンピュータハードウェアの詳細から高く抽象化されたプログラミング言語であり[1]、主に1950年代以降に実用化が進んだ。

高水準言語は、レジスタやメモリアドレス、呼び出しスタックといったプロセッサ固有の概念ではなく、変数、配列、オブジェクト、算術式、ブール式関数、ループ、スレッドなどの抽象概念を用いてプログラムを記述する。このような抽象化の程度が、その言語がどの程度「高水準」であるかを定義する[2]

概要

代表的な言語としてはJavaなどがある他、特にきわめて抽象度が高い言語としてはHaskellなどがある。

高水準言語は、低水準言語と比べ、以下のような特徴を持つ。

  • 人間にとって理解しやすい構文を持つ
  • 特定のプロセッサに依存した処理を書かなくてよい
  • メモリ管理や入出力制御などの低水準操作を自動化、あるいは隠蔽する
  • プログラムの可読性や保守性を高めやすい

一方で、高水準言語の多くは機械語のオペコードに直接対応する言語要素をほとんど持たない。そのため、ソースコードはハードウェアから切り離された形で記述される。プログラマの明示的な記述なしにデータ移動などが行われる場合もある。

歴史

1960年代には、コンパイラを用いる高水準言語を「オートコード」と呼ぶこともあった。代表例としてCOBOLFortranがある。

最初期の高水準言語としては、コンラート・ツーゼにより設計されたプランカルキュールがあるが、当時は実装されなかった。

広く普及した最初期の高水準言語はFortranである。これはIBMのオートコード系言語を発展させ、機械非依存性を高めたものである。

ほぼ同時期に、欧米の研究者によってALGOL系言語(ALGOL 58、ALGOL 60)が開発された。ALGOLは再帰、静的スコープに基づく入れ子関数、値渡しと名前渡しの明確な区別などを導入し、さらにバッカス・ナウア記法(BNF)によって文法を形式的に定義した最初の言語となった。

Lispは完全なラムダ計算に基づく抽象機能を実装した最初期の言語であり、COBOLレコード構造を広く普及させた。

抽象化の代償

高水準言語は、共通処理の標準化、豊富なデバッグ支援、アーキテクチャ非依存性といった利点を持つ。一方で、低水準言語と比べると、抽象化による性能上の「代償」が存在するとされる。

低水準言語ではハードウェア資源を直接制御できるため、極限的な最適化が可能である。しかし実際には、ユーザー体験レベルで性能差が顕著になることは多くないとする研究もある[3][4]。性能やメモリ制約が厳しい箇所のみをアセンブリ言語で記述し、他を高水準言語で実装する手法も広く用いられている。

また、適切に設計されたコンパイラは、人手によるアセンブリコードと同等、あるいはそれ以上に効率的なコードを生成できる場合もある[5]

相対的概念

「高水準」と「低水準」という分類は本質的に相対的なものであり、ある言語が他の言語より高水準である、あるいは低水準である、と比較される。

例えば、C言語は文脈によって高水準言語とも低水準言語とも見なされることがある。C言語は式評価、引数付き関数、再帰呼び出し、構造体など、アセンブリ言語やプロセッサが直接は提供しない抽象機能を備えている。この点ではアセンブリ言語より高水準である。

一方で、C言語はポインタによるアドレス操作、手動メモリ管理、ビット単位操作など、ハードウェアに近い制御を可能にする。また、ガーベジコレクションや組み込みの文字列型など、より高水準の言語で一般的な機能は標準仕様には含まれていない。そのため、多くの現代的言語と比較すると低水準寄りと位置付けられることもある。

実際、ブライアン・カーニハンデニス・リッチーは『プログラミング言語C』第2版の序文において、Cを「それほど高水準ではない(not a very high level)」言語と述べている[6]

同様に、アセンブリ言語機械語よりは抽象度が高いが、依然として特定のプロセッサ・アーキテクチャに強く結びついている。

さらに、機械語もまた、多くのプロセッサ内部で用いられるマイクロコードマイクロオペレーションと比較すれば、わずかに高い抽象度を持つといえる[7]

このように、「高水準」「低水準」という区分は絶対的な境界を持つものではなく、対象や比較関係によって変化する概念である。

実行形態

高水準言語のソースコードは、以下のような形で処理される。

コンパイル
コンパイラによりネイティブ機械語、あるいはバイトコードなどの中間表現へ変換される。中間表現は実行時にJITコンパイルされる場合もある。
インタプリタ実行
インタプリタがソースコードまたは中間コードを逐次解釈して実行する。
トランスパイル
他の言語(多くはより低水準の言語)へソースコード変換する。C言語JavaScriptなどが変換先として利用されることがある。
ハードウェア直接実行
まれではあるが、高級言語計算機のように、高水準言語を直接実行対象とするアーキテクチャも存在する。

なお、ある言語が「コンパイル言語」か「インタプリタ言語」かという分類は厳密ではなく、実装方式に依存する。たとえばJavaはバイトコードへコンパイルされ、その後仮想機械上で実行される。

その他

高水準言語とハードウェアとの間には、大きなセマンティックギャップがある。そのギャップを埋めるのがコンパイラインタプリタといったプログラミング言語処理系である。このギャップを縮小するため、過去にはさまざまな試みがなされてきた。

ひとつは、ハードウェアを高水準言語寄りに設計する試みである。例として、1961年のバロース B5000LISPマシンメインフレームにおけるCOBOL命令支援、ARMアーキテクチャのJazelleなどがある(高級言語計算機)。

もうひとつは、コンパイラ技術の高度化である。RISCはハードウェアを単純化し、コンパイラ最適化に重点を置く思想であった。一方で、TRONCHIPのようにコンパイラが利用しやすい複雑命令を備える設計も存在した。

脚注

関連項目

Related Articles

Wikiwand AI