導入
| 対物レンズ | |
| に登場 | 1987年(CAML)、1996年(OCaml) |
|---|---|
| 開発者 | インリア |
| 最新バージョン | 3.12.0 [+/-] |
| パラダイム | マルチパラダイム: 命令型、関数型、オブジェクト指向 |
| タイピング | 騒々しい、静的な |
| 方言 | JoCaml、Fresh OCaml、GCaml、MetaOCaml、OCamlDuce、OcamlP3L |
| 影響を受けた | ML(言語) |
| 影響を与えた | F# |
| オペレーティング·システム | マルチプラットフォーム |
| ライセンス | Qパブリックライセンス(コンパイラ) LGPL (図書館) |
| Webサイト | http://caml.inria.fr/ |
Objective Caml (省略形OCamlとも呼ばれます) は、1996 年にXavier Leroy 、 Jérôme Vouillon 、 Damien Doligez 、 Didier Rémyとその協力者によって作成された、Caml プログラミング言語の最も先進的な実装です。この言語は、ML 言語ファミリーに属します。は、主に INRIA によって主導および維持されているオープンソースプロジェクトです。
OCaml はCaml Lightの後継であり、特にオブジェクトプログラミング層が追加されています。 CAML の頭字語は、抽象マシン モデルであるCategorical Abstract Machine Languageに由来していますが、最近のバージョンの OCaml では使用されなくなりました。
ポータブルで強力な OCaml は、Unisonファイル同期ソフトウェア、正式な証明アシスタントCoq 、 Microsoftによって作成された静的Windowsドライバー検証ツールなど、さまざまなプロジェクトで使用されています。

原則
Caml は、 命令型プログラミングを可能にする機能が強化された関数型言語です。 Objective Caml は、 オブジェクト指向プログラミングとモジュール型プログラミングを可能にすることで、言語の可能性を拡張します。これらすべての理由により、OCaml はマルチパラダイム言語のカテゴリーに分類されます。
これらのさまざまな概念を、静的、強力、推論された型付けによって特徴づけられる、ML から継承された型システムに統合します。
型システムを使用すると、複雑なデータ構造を簡単に操作できます。代数型、つまり階層的で再帰的な型 (リスト、ツリーなど) を簡単に表現でき、パターン フィルターを使用してそれらを簡単に操作できます。このため、OCaml は、コンパイラなど、複雑なデータ構造の操作が必要な分野で最適な言語となっています。
OCaml は、強力な型付けと、明示的なメモリ操作がない (ガベージ コレクターの存在) ことにより、非常に安全な言語となっています。ネイティブ コードコンパイラーの存在によるパフォーマンスでも有名です。
主な特長
関数型言語
OCaml には、関数型言語の一般的な機能のほとんどがあり、特に高階関数とクロージャーがあり、末尾再帰が適切にサポートされています。

タイピング
OCaml の静的型付けは、実行時に問題を引き起こす可能性のある多数のプログラミング エラーをコンパイル時に検出します。ただし、他のほとんどの言語とは異なり、使用している変数のタイプを指定する必要はありません。実際、Caml には、変数が使用されているコンテキストから変数の型を決定できる型推論アルゴリズムがあります。
ML 型付けシステムは、パラメトリック多態性、つまり、値が設定されたときにその部分が決定されない型をサポートします。この自動機能により、Java や C# のジェネリックス、または C++テンプレートに匹敵するジェネリック性を得ることができます。
ただし、オブジェクト指向プログラミングなどの高度な機能の統合に必要な ML タイピングの拡張により、場合によっては型システムが複雑になります。これらの機能の使用には、プログラマーの学習時間が必要になる可能性がありますが、プログラマーは必ずしも必要ではありません。洗練された型システムに精通している。
フィルタリング
パターン マッチングはCaml 言語の重要な要素です。従来の条件より柔軟な記述によりコードの軽量化が可能となり、不完全なフィルタリングが検出された場合にはコンパイラが反例を提供するなど完全性がチェックされます。たとえば、次のコードはコンパイルされますが、警告が発生します。
#状態タイプ=アクティブ|非アクティブ|未知;; # (* 合計タイプ: 状態は 3 つの値のいずれかです: アクティブ、非アクティブ、不明 *) # let is_active = function Active -> true |非アクティブ-> false ;;
警告 P: このパターン マッチングは網羅的なものではありません。一致しない値の例を次に示します: 不明
したがって、プログラムは is_active 関数がアクティブまたは非アクティブのステータスで呼び出された場合に動作しますが、ステータスが不明の場合、関数はMatch_failure例外をスローします。
モジュール
モジュールを使用すると、論理的に関連する型と値を含む構造の階層にプログラムを分解できます (たとえば、すべてのリスト操作関数は List モジュールに入れられます)。 ML ファミリーの子孫は、現在最も高度なモジュール システムを備えた言語であり、名前空間を持つことに加えて、抽象化(実装が隠されているアクセス可能な値) と合成可能性 (実装が隠されているアクセス可能な値) を実装することができます。特定のインターフェイスに応答する限り、さまざまなモジュールの上に構築されます)。
したがって、構文構築の 3 つの構文単位は、構造、インターフェイス、およびモジュールです。構造体にはモジュールの実装が含まれ、インターフェイスにはそれらにアクセスできる値が記述されます(実装が公開されていない値は抽象値であり、モジュール実装にまったく表示されない値はアクセスできません。たとえば、オブジェクト指向プログラミング)。モジュールは複数のインターフェイスを持つことができ (すべてのインターフェイスが実装タイプと互換性がある限り)、複数のモジュールが同じインターフェイスをチェックできます。ファンクターは、他の構造によってパラメータ化された構造です。たとえば、OCaml標準ライブラリのハッシュ テーブル (Hashtbl モジュール) は、型、キー間の等価関数、およびハッシュ関数で構成されるインターフェイスを実装する任意の構造をパラメータとして受け取るファンクターとして使用できます。
オブジェクト指向
OCaml は、古典的なオブジェクト言語で使用されているものと同等のオブジェクト システムに向けた ML タイピングの拡張によって特に際立っています。これにより、オブジェクトのメソッドの型に互換性がある場合、オブジェクトのそれぞれの継承ツリーに関係なく、型の互換性がある構造サブタイピングが可能になります。この機能は動的言語におけるダックタイピングに相当すると考えることができ、一般的な関数型言語におけるオブジェクト概念の自然な統合を可能にします。
したがって、すべてのクラスが型を定義する C++ や Java などのオブジェクト指向言語とは異なり、OCaml クラスは型の省略形を定義します。実際、メソッドのタイプに互換性がある限り、2 つの異なるクラスの 2 つのオブジェクトを同じコンテキスト内で区別なく使用できます。 OCaml オブジェクト層のこの特性は、一般に受け入れられている多くの原則を破るものです。たとえば、継承を行わずにサブタイプを実行することは実際に可能です。ポリモーフィックな側は、反対の原則を打ち破ります。まれではありますが、サブタイプなしの継承のケースを示すコード例も存在します。
オブジェクト層の強みは、その均質性と、OCaml 言語の哲学および精神そのものへの完全な統合にあります。属性を変更できず、必要に応じてメソッドが属性の更新、直接オブジェクトの定義、またはオンザフライでコピーを返す機能オブジェクトも可能です。

分布
OCaml ディストリビューションには次のものが含まれています。
- 対話型インタプリタ (ocaml)
- バイトコード コンパイラ (ocamlc) とバイトコード インタープリタ (ocamlrun)
- ネイティブコンパイラ (ocamlopt)
- 字句解析 (ocamllex) および構文解析 (ocamlyacc) ジェネレーター、
- 言語構文の拡張または変更を可能にするプリプロセッサ(camlp4)
- バックトラック機能を備えたステップバイステップのデバッガ(ocamldebug)
- プロファイリングツール
- ドキュメントジェネレーター(ocamldoc)
- OCaml 3.10 以降の自動コンパイル マネージャー (ocamlbuild)、
- 多彩な標準ライブラリ
OCaml ツールは、Windows、GNU/Linux、またはMac OSで通常使用されますが、BSD などの他のシステムにも存在します。
バイトコード コンパイラを使用すると、ocamlrun によって解釈されるファイルを作成できます。バイトコードはプラットフォームから独立しているため、優れた移植性が保証されます (ocamlrun は、機能的な C コンパイラをサポートする任意のプラットフォームで事前にコンパイルできます)。ネイティブ コンパイラはプラットフォーム固有のアセンブリコードを生成しますが、パフォーマンスを大幅に向上させるために、生成された実行可能ファイルの移植性が犠牲になります。 IA32、 PowerPC 、 AMD64 、Alpha、 Sparc 、Mips、IA64、HPPA、および StrongArm プラットフォーム用のネイティブ コンパイラが存在します。
互換性インターフェイスにより、OCaml コードを C プリミティブにリンクでき、浮動小数点配列の形式は C およびFortranと互換性があります。 OCaml では、OCaml コードを C プログラムに統合することもできるため、OCaml を知らなくても、インストールしなくても、OCaml ライブラリを C プログラマに配布できます。
OCaml ツールは、C でコーディングされているいくつかのライブラリとバイトコード インタプリタを除いて、主に OCaml でコーディングされています。特に、ネイティブ コンパイラは完全に OCaml でコーディングされています。
メモリ管理
OCaml は、Java と同様、世代別増分ガベージ コレクターのおかげでメモリ管理を自動化しました。これは関数型言語に特別に適合されているため (小さなオブジェクトの割り当て/解放が高速になるように最適化されています)、プログラムのパフォーマンスに大きな影響はありません。異常なメモリ使用状況でも効果を維持するように構成できます。
パフォーマンス
OCaml は、その優れたパフォーマンスにより、学術環境で開発されたほとんどの言語より際立っています。ネイティブ コード ジェネレーターによって実行される「古典的な」ローカル最適化に加えて、言語の機能的かつ静的かつ厳密に型指定された性質によってパフォーマンスが有利に向上します。
したがって、型付け情報はコンパイル時に完全に決定され、ネイティブ コードで再現する必要がないため、実行時に型付けテストを完全に削除できます。一方、標準ライブラリの特定のアルゴリズムは、純粋関数型データ構造の興味深い特性を利用しています。したがって、set Union アルゴリズムは、非可変性を利用して開始セットの一部を再利用するため、命令型言語よりも漸近的に高速になります。出力セットを構成します (これは永続的なデータ構造のパス コピー手法です)。
歴史的に、関数型言語は、効率的にコンパイルする方法が分からない概念 (メモリ コレクション、部分的なアプリケーションなど) の実装を自然に必要とするため、一部のプログラマには遅いと考えられてきました。その後、コンパイル技術の進歩により、命令型言語の当初の利点を上回ることが可能になりました。 OCaml は、言語のこれらの部分を効率的に最適化し、関数型言語の頻繁な割り当てに適応したガベージ コレクターを実装することにより、 関数型プログラミングの新たな効率性を実証した最初の関数型言語の 1 つです。
一般に、実行速度は C の同等のコードよりもわずかに遅くなります。Xavier Leroy は慎重に「合理的な C コンパイラの少なくとも 50% のパフォーマンス」について語っています。これらの予測はその後、多数のベンチマークによって確認されました。実際には、プログラムは通常、この範囲内 (C コードの 1 ~ 2 倍) に収まりますが、両方向に極端な場合もあります (場合によっては C よりも高速になることもありますが、ガベージ コレクターとの不幸なやり取りによって大幅に遅くなる場合もあります)。いずれの場合でも、Python、 Ruby 、さらには .NET プラットフォーム言語など、ネイティブにコンパイルできないほとんどの言語よりも高速です。
コードの構造に関しては、プログラムのアーキテクチャを強調したり正しく構成したりできるモジュールが含まれています。静的型付けでは、これは21世紀のプログラマーにとって不可欠なパフォーマンスであり、実行速度は二次的な基準になります。
