Chicken ( CHICKENと表記されることもある) はプログラミング言語であり、具体的にはScheme 言語の方言を実装したコンパイラおよびインタプリタで、Schemeソース コードを標準Cにコンパイルします。大部分はR5RSに準拠しており、標準に対する多くの拡張機能を提供しています。より新しい R7RS 標準は拡張ライブラリを通じてサポートされています。[ 2 ] Chicken はBSD ライセンスで利用可能なフリーのオープンソース ソフトウェアです。大部分は Scheme で実装されていますが、パフォーマンス向上や C プログラムへの組み込みを容易にするために一部は C で実装されています。
Chickenのスローガン「実用的で持ち運び可能なスキームシステム」から、その焦点はすぐに明らかになる。
Chicken の主な焦点は、実世界のソフトウェアを作成するための Scheme の実践的な応用です。Scheme はコンピュータサイエンスのカリキュラムやプログラミング言語の実験でよく知られていますが、ビジネスや産業ではほとんど使用されていません。[ 3 ] Chicken のコミュニティは、さまざまなタスクを実行するためのライブラリを多数作成しました。Chicken wiki (それを実行するソフトウェアも Chicken プログラムです) には、Chicken で書かれたソフトウェアのリストも含まれています。[ 4 ]
Chicken のもう 1 つの目標は移植性です。中間表現、この場合は移植可能な C ( GambitやBiglooと同様) にコンパイルすることで、Chicken で書かれたプログラムは、Linux、macOS、その他のUnix 系システム、Windows、Haiku、モバイル プラットフォームiOSやAndroidなどの一般的な人気オペレーティングシステム向けにコンパイルできます。[ 5 ]また、クロス コンパイルプログラムと拡張機能のサポートも組み込まれており、 [ 6 ]さまざまな組み込みシステムプラットフォームで使用できます。
多くのSchemeコンパイラと同様に、Chickenは中間表現として標準C言語を使用します。SchemeプログラムはChickenコンパイラによってC言語に変換され、その後Cコンパイラによってターゲットコンピュータアーキテクチャ用の機械語に変換され、実行可能プログラムが生成されます。C言語は広く普及しているため、この目的に適しています。
Chicken の設計は、Scheme を C にコンパイルする革新的な戦略を概説したHenry Bakerによる1994 年の論文[ 7 ]に触発されたものです。Scheme プログラムは C関数にコンパイルされます。これらの C 関数はreturn文に到達せず、完了すると新しい継続を呼び出します。これらの継続は C 関数であり、追加の引数として他の C 関数に渡されます。これらはコンパイラによって計算されます。
ここまでが継続渡しスタイルの本質です。 ベイカーの斬新なアイデアは、C のコールスタックをScheme のヒープに使用することです。そのため、自動変数作成、可変サイズの配列割り当てなど、通常の C スタック操作を使用できます。スタックがいっぱいになると (つまり、スタックポインタがスタックの最上部に達すると)、ガベージコレクションを開始できます。使用されている設計は、 CJ チェイニーが考案したコピーガベージコレクタで、すべての生存継続と他の生存オブジェクトをヒープにコピーします。[ 8 ] それにもかかわらず、C コードは C スタックフレームをコピーせず、Scheme オブジェクトのみをコピーするため、C 実装の知識は必要ありません。
Scheme のヒープは、C スタックを子機として、世代別ガベージコレクタに必要な 2 つのヒープと組み合わせたものです。このアプローチにより、多くの操作で C スタックの速度が得られ、継続を C 関数への単純な呼び出しとして使用できます。さらに、Baker のソリューションは、Scheme 言語標準で要求されているように、漸近的な末尾再帰動作を保証します。Chicken Scheme コンパイラでの実装は、スペースに関しても漸近的に安全です。
Chicken Scheme は、いくつかの注目すべき制限と逸脱を除いて、ほとんど R5RS に準拠しています。[ 9 ] R7RS との互換性は拡張ライブラリとして提供されます。[ 2 ]
コアシステムはUTF-8文字の基本的なサポートを備えていますが、文字列のインデックス付けと操作手順はUTF-8に対応していません。完全なUTF-8対応をサポートする拡張ライブラリが存在します。[ 10 ]
Chickenには、追加ライブラリやプログラム(eggsと呼ばれる)の大規模なソフトウェアリポジトリがあります。[ 11 ]このシステムはRubyGemsと非常によく似ています。[ 12 ]
当初、これらの egg は 1 つの中央 svn リポジトリで開発され、[ 13 ]タグを作成すると、拡張機能の新しいバージョンが自動的にダウンロード可能になりました。現在では、egg はどこでも、どのバージョン管理システムでも開発でき、ほとんどの一般的なコード ホスティング サイトを使用する場合でも、半自動のリリース管理を維持しています。[ 14 ]このリリース方法は、ユーザーがこれらの VCS をインストールする必要がないという意味で、VCS に依存しません。開発者は好きな場所にホストすることができ、公開バージョン管理を避けて、プレーンな tarball のみを配布することもできます。
リリースされたすべてのエッグについて、最新バージョンは継続的インテグレーションプロセスの一環として自動的にテストされます。標準テストサーバー[ 15 ]が存在し、コアシステムとすべてのエッグは、最新の開発バージョン(後退バグを検出するため)と最新の安定バージョン(安定システムのユーザーにとってすべてが正常に動作することを保証するため)に対して毎日テストされます。また、誰でも、さまざまなハードウェア、オペレーティングシステム、またはコアリリースで、追加のテスト能力を提供することを志願できます。
ChickenはR5RS標準Schemeのほとんどをサポートしていますが、すべてのScheme実装で利用できるわけではない、いくつかの非標準機能も追加しています。
ChickenはC言語にコンパイルできるため、コンパイル結果に独自のCコードを挿入することが可能で、Cライブラリとの統合が容易になります。また、外部関数インターフェースは、ほとんどの組み込みC型と対応するSchemeオブジェクト間の相互変換をサポートしています。
また、Java Native Interface (JNI) [ 18 ]またはブリッジ[ 19 ]を介してPython [ 16 ] Lua [ 17 ]およびJavaとインターフェースするための拡張ライブラリも存在します。
Schemeコードを別のプラットフォーム(例えば、デバイスへの組み込み用途)向けにクロスコンパイルすることは比較的容易です。
Scheme コードのクロスコンパイルを可能にするために、Chicken は分離コンパイルのモデルを採用しています。コンパイルされたモジュールは、2 つの共有ライブラリで構成されます。1 つのライブラリには、実行時に使用される実際のコード (ターゲット プラットフォーム用にコンパイル済み) が含まれており、もう 1 つはインポート モジュールで、手続き型マクロ コードなど、コンパイル時 (ホスト プラットフォーム上) に実行されるコードをロードするために使用されます。
Chickenコンパイラはクロスコンパイルも容易です。C言語への変換が完了したら、別のプラットフォーム向けにビルドするように設定されたCコンパイラを使用するだけで済みます。
バージョン4以降、Chickenには組み込みのモジュールシステムと、明示的な名前変更マクロ[ 20 ]による低レベルの衛生的なマクロのサポートがあります(バージョン4以前は、これはアドオンライブラリを介して利用可能でした)。標準構文ルールマクロもサポートされており、暗黙的な名前変更マクロ[ 21 ]は基本的に明示的な名前変更の逆バージョンです。
このメカニズムは、利便性と引き換えにパフォーマンスを犠牲にしています。明示的に不衛生として指定されていない識別子は、名前のキャプチャを回避するために自動的に名前が変更されます。暗黙的な名前変更にはマクロ展開装置が式をさらに2回走査する必要があるため、パフォーマンス上のコストが発生します。このコストは展開時に発生するため、マクロ作成者はコンパイル時間の増加が許容できるかどうかを検討する必要があります。
バージョン 4.11 以降、Chicken にはFeathersという名前のデバッガが同梱されています。[ 22 ] Scheme コードを必要なデバッグ オプションでコンパイルすると、コードの特定の箇所にデバッグ イベントが挿入されます。これらは C 関数の呼び出しとして実装されており、実際にコードをデバッグしていないときは比較的オーバーヘッドが低くなっています。デバッグ中は、別のマシン上にある可能性のある Feathers サーバー プロセスへの TCP 接続を試みます。プロセスが停止すると、ユーザーはブレーク ポイントを設定してプログラムを開始できます。その後、ブレーク ポイントに到達すると、クライアント (デバッグ中のプロセス) はコマンド ループに入り、クライアントを照会して変数を読み出したり、変数を変更したりできます。
Chickenはローカルフロー解析をサポートしています。これにより、コンパイラはコンパイル時に変数型のエラーを検出し、型特殊化を実行できます。この特殊化により、コンパイル時に型を推論できる場合、実行時の型検出に関するいくつかの安全チェックを省略することが可能になります。その結果、実行時パフォーマンスが向上します。
このスクルーティナイザーはモジュール間のフロー分析を許可していないため、単一のコンパイル単位(またはモジュール)に含まれるコードの最適化にのみ使用できます。
CHICKEN Schemeは、元々はFelix WinkelmannがCygwin /gcc上で開発し、後にWindows 98上のVisual C++ 5.0で開発されました。[ 1 ]彼は机の上にあるFeathers McGrawのプラスチック製のおもちゃを思い浮かべ、「その日最初に頭に浮かんだもの」として、恣意的に「CHICKEN」という名前を思いつきました。プロジェクトが成熟するにつれて、彼は迷信から名前を変えないことに決めました。[ 23 ]