私の観察によると、 cllリストまたは別のLispリストで少なくとも週に1回、初心者はパッケージに関連するものについて混乱します。 彼らはパッケージの「ロード」、パッケージの「要求」について話し、システムをロードした後にパッケージマーカーなどを使用する必要があることに驚いています。 それは私を困らせます、また、これは初心者がLispでライブラリを使うのが実際よりも複雑だと思う理由の一つかもしれないと思います。
通常、有用な説明を書こうとするのをやめます。当然、この説明は非常に簡単です。 このページを作成したのは、同じことを繰り返し説明する代わりに、次回ここに送信できるようにするためです。
まず第一に、あなたは明確な頭を持っている必要があります。 「パッケージ」という用語は非常に過負荷です。 DebianやGentooなどのLinuxディストリビューションには「パッケージ」があり、「パッケージ」はJava、Perl、またはPythonプログラミング言語です。 「パッケージ」とは何か、それがどうあるべきかについて偏った意見でLispに来た可能性があります。
パッケージ
Common Lisp のパッケージは、標準で明確に定義されたセマンティクスを持つ言語の本格的な要素です。 さらに、このページで説明したすべての用語の中で、これは(Common Lispのコンテキストで)明確な定義を持つ唯一のものです。 パッケージは、厳密に言えば、キャラクターのコンテナです。 プログラム内の個別の名前空間を整理するために必要であると言えます。
Common Lispには、パッケージを作成、変更、検査、および削除するための関数とマクロがあります。 パッケージ(およびシンボル)の非常に優れた紹介は、 Peter Sibelの優れたPractical Common Lispの21章にあります。 この用語の定義は、 ANSI Common Lisp仕様の 第11章 (オンライン版)にあります。
一般的に、それはパッケージに関するすべてです。 技術的に言えば、あなたはパッケージをダウンロードしていません。 コードをダウンロード(
LOAD
を使用)することができます。これにより、パッケージが作成されますが、これは大きな違いです。
さらに、Lispがパッケージを見つけられないと文句を言う場合、これはLispオブジェクトとしてのパッケージがイメージにないことを意味します(つまり、
FIND-PACKAGE
は
NIL
返します)、まだ誰も作成していないからです。 これは、Lispマシンがファイルシステムを検索して何も見つからなかったことを意味するものではありません。 (この失敗の一般的な理由は、イベントが間違った順序で発生することです。以下を参照してください。)
システム
システムは、パッケージとは異なり、 標準では言及されていません。 しかし、経験豊富なLispプログラマーは、ある種のシステム定義ツールを知って適用する必要があるため、この用語を知っています。 今日最も注目すべきは、 ASDF (ほとんどのオープンソースLispライブラリで使用)です。 ASDFよりもはるかに古い別のよく知られたシステム定義ツールはMK:DEFSYSTEMです。 一部の開発者は、システム定義ツールにディストリビューションも提供しています。たとえば、 LispWorksのCommon Defsystemを参照してください。
この脈絡で、厳密に言えば、システムとは、他のシステム、最初にダウンロード/コンパイルする必要があるものなどに応じて、コードとそれを処理するための命令のセットです。 つまり、システム定義ツールのデザインはmakeまたはAntに似ています。
さらに、通常、システム定義ツールはさらに多くのことができます-Common Defsystemは、たとえば、 COMタイプのライブラリファイルを統合できます 。ASDFは完全に拡張可能で、特にCでファイルをコンパイルするために使用されました。 また、記述されたシステムのテストスイートを定義するためにもよく使用されます 。
ASDFは非常に人気がありますが、遍在していません。 SBCL、OpenMCL、AllegroCLなどの多くのLispシステムがプリロードされており、他のLispシステムで起動する可能性が高いですが、この事実はCommon Lispの一部ではありません。 これは、明示的な仕様がなく、互いに互換性のない異なるバージョンのコードのセットです。
理解してください...
モジュール
標準ではモジュールを表面的にのみ定義しています。
REQUIRE
、
PROVIDE
、および
*MODULES*
について知っておく必要がある2つのことがあります-この機能は非推奨であり、実装に依存します。 この機能が推奨されていないという事実に悩まされることはありません。 現在、すべてのディストリビューションにはこれらの関数が含まれており、新しいANSI標準が登場し、すべての実装がそれらを突然削除する可能性はもちろん小さいです。 心配する
REQUIRE
は、
REQUIRE
が便利ではあるが移植性のない方法になる可能性があることです(もちろん、移植性のメカニズムを心配しているのでなければ)。
たとえば、LispWorksでは次を使用できます
(require "foreign-parser")
Cの定義を読み取ることができるパーサーをロードしますが、これはOpenMCLでは機能しません。 また呼び出すことができます
(require :asdf)
LispWorksではなくOpenMCLでASDFをダウンロードします。
一部のディストリビューションは
REQUIRE
を設定するためのフックを提供し、REQUIREをASDFに接続するcommon-lisp-controllerなどの拡張機能がありますが、一般に、モジュールは実装固有のものであり、システム(ASDF)と混同しないでください。 、特にパッケージの場合。
図書館
ほとんどの場合、ライブラリとは何かを明確に定義することはできません。 ほとんどの人は、1つまたは複数の特定のタスクを実行するように設計され、全体として配布されるコードのコレクションであると考えています。通常はどこかからダウンロードできる圧縮アーカイブの形式です。 実際、この不明確な定義は、Lispで書かれたプログラムについて話すときに最も適していると思います。 現在、ほとんどのLispライブラリにはシステム定義(ASDF)が含まれていますが、これは必須ではありません。 おそらく、取得方法によっては、これはLispシステムのモジュールになりますが、これも必要ではありません。 さらに、ライブラリは通常、1つ以上のパッケージを定義しますが、定義しない場合もあります。
また、合意によって、またはおそらく想像力の欠如が原因で、KuライブラリにKuシステムとして定義されているKuシステムの定義が付属している場合、状況が発生することがあります。 コードをダウンロードしたら、「Ku」という新しいパッケージを取得します。 同じ名前の4つの異なるエンティティ! これは混乱を招くことは認めますが、前のいくつかの段落が状況を少し明確にする助けになることを願っています。
しかし、私にはまだ何も機能しません!
多くの場合、人々は次のようなコードを含むファイルをコンパイルできないと不平を言います。
;; (require :cl-ppcre) (asdf:oos 'asdf:load-op :cl-ppcre) (defun my-simple-number-scanner (string) (cl-ppcre:scan "^[0-9]+$" string))
なぜそう このファイルをダウンロードできるのにコンパイルできないのはなぜですか? そして、ロード後にコンパイルできるのはなぜですか? 変じゃない?
いいえ、奇妙ではありません。 コンパイラーは、最初のフォーム(必要に応じてコンパイルする命令です)を読み取り、CL-PPCREシステムをロードしますが、実行しません。最終的に、コンパイラーはコードのコンパイルのみに関心があります。ここでエラーメッセージが表示される可能性があります。このフォームを読み取ろうとするLispスキャナーは、「cl-ppcre:scan」という文字シーケンスを検出するためです。システムブートCL-PPCRE、 とりわけ、CL-PPCREパッケージが作成されていますが、これはまだ行われていませんCLHSの第3章を読んでください。
EVAL-WHEN
を使用して、2番目のフォームを読み取る前にCL-PPCREをロードするようコンパイラーに指示できます。 ただし、コードを整理する別の方法を見つける必要があります。 最初の形式は、コードがCL-PPCREシステムに依存していることを単に通知するものです。 これは、Lispコードと同じファイルにあるべきではありません。 プログラムのシステム定義を作成し 、依存関係をそこに配置します。