Common Lisp

提供: ArchWiki
ナビゲーションに移動 検索に移動

Common Lisp は、高度に動的でマルチパラダイムの言語であり、インタラクティブ性とパフォーマンスを重視しています。完全に標準化されているため、複数の独立した実装から選択できます。

インストール

sbcl (http://www.sbcl.org/) は最も人気のある FOSS 実装であり、エコシステム全体で一般に最高の互換性を持っています。そのコンパイラはネイティブマシンコードを生成し、プロジェクトは毎月リリースされます。

~/.sbclrc 内の Lisp で設定されますが、依存関係管理戦略によっては必要ない場合があります。

代替実装

他にも多数の実装が利用可能です。以下のオプションとは別に、2つの主要な商用 Lisp 実装であるAllegroとLispWorksがありますが、厳格なライセンス条項があり、Arch Linux エコシステム内ではパッケージ化されていません。

アクティブ

これらは最新のツールとシームレスに機能し、本格的なプロジェクトに使用できます。

  • ABCL — Armed Bear Common Lisp: Java仮想マシン上で実行されます。
https://common-lisp.net/project/armedbear/ || abclAUR
  • CCL — Clozure Common Lisp: Open Macintosh Common Lispに基づいており、コンパイル時間の速さで知られています。
https://ccl.clozure.com/ || cclAUR
  • Clasp — Clasp: C++ライブラリと相互運用し、ネイティブコードへのコンパイルにLLVMを使用する、比較的新しいCommon Lisp実装です。
https://clasp-developers.github.io/ || clasp-clAUR
  • ECL — Embeddable Common Lisp: Cコードにコンパイルされるため、優れたC統合と埋め込み機能を提供します。
https://common-lisp.net/project/ecl/ || ecl

歴史

これらのパッケージは利用可能ですが、ライブラリとツールの互換性が疑わしい場合があり、一部の実装はもはや活発にメンテナンスされていません。

  • CLISP — ANSI Common Lisp インタプリタ、コンパイラ、デバッガ: 優れたC統合と埋め込み機能を提供します。
https://www.gnu.org/software/clisp/ || clisp
  • CMUCL — CMU Common Lisp: 元々カーネギーメロン大学で開発された POSIX のみの実装です。
https://gitlab.common-lisp.net/cmucl/cmucl/-/wikis/home || cmucl
  • GCL — GNU Common Lisp: 80年代の Kyoto Common Lispの子孫であり、ECL の兄弟です。
https://www.gnu.org/software/gcl/ || gclAUR
  • MKCL — Mankai Common Lisp: Kyoto Common Lisp の同様の子孫です。
https://mkcl.common-lisp.dev/ || mkcl-gitAUR

依存関係管理

Common Lisp の依存関係管理は、従来 Quicklisp を使用していましたが、近年、現代的な代替手段が登場しています。

Vend

Vend は、プロジェクトリポジトリ内で直接依存関係をダウンロードしてアクセスするためのシンプルなツールです。特別な設定は必要ありません。

vendAURパッケージをインストールした後、プロジェクトのトップディレクトリから vend get を実行できます:

[vend] Downloading dependencies.
[vend] Fetching FN-MACRO
[vend] Fetching ARROW-MACROS
[vend] Fetching TRANSDUCERS
...
[vend] Done.

その後、vend repl が REPL セッションを開始します。

エディタ統合

Emacs

Sly/Slime の Emacs ユーザーの場合、エディタ内 REPL は次のように設定できます:

(setq sly-default-lisp 'sbcl
      sly-lisp-implementations '((sbcl ("vend" "repl" "sbcl")  :coding-system utf-8-unix)
                                 (ecl  ("vend" "repl" "ecl")   :coding-system utf-8-unix)))

同様の方法で他のコンパイラを自由に追加できます。Slime に合わせて適宜調整してください。

Lem

Lem のユーザーは、次のコマンドでREPLを開くことができます:

C-u M-x slime <RET> vend repl
Vim

複数の実行中の Lisp をサポートする Emacs とは異なり、Slimv は Vim の再起動を通じて持続するスタンドアロンサーバーを1つ必要とします。

vendored/ の依存関係を Slimv から見えるようにするには、プロジェクトディレクトリから手動でサーバーを起動する必要があります:

> cd project/
> vend repl ecl --load /home/YOU/.vim/pack/common-lisp/start/slimv/slime/start-swank.lisp

これで、Vim 内の ,c (REPL 接続) が実行中のサーバーを自動的に検出し、プロジェクトと vendored/ で使用可能な任意のシステムをロードできます。

プロジェクトを切り替える場合は、REPL サーバーを手動で終了し、上記のように再起動する必要があります。上記のような長い呼び出しのためにシェルエイリアスを設定するか、ラッパースクリプトを作成することもできます。

OCICL

OCICL は Quicklisp の現代的な代替であり、OCI 準拠のアーティファクト としてパッケージを集中管理されたパッケージリポジトリから配布します。Quicklisp と同様に、依存関係のロードを引き継ぎ管理するためにユーザーが設定する必要があります。

ociclAUR パッケージをインストールした後、ocicl setup を実行します。これにより、コンパイラ設定ファイルに以下が追加されます:

#-ocicl
(when (probe-file #P"/home/green/.local/share/ocicl/ocicl-runtime.lisp")
  (load #P"/home/green/.local/share/ocicl/ocicl-runtime.lisp"))
(asdf:initialize-source-registry
  (list :source-registry (list :directory (uiop:getcwd)) :inherit-configuration))

これで、REPL 内で、未知の依存関係に対して (asdf:load-system :foo) を実行しようとすると、自動的にダウンロードされます。追加のプロジェクト設定は systems.csv ファイルで行われ、プロジェクトリポジトリにコミットすることを意図しています。設定と使用方法の詳細については、README を参照してください。

Quicklisp

Quicklisp は、Common Lisp プログラムにライブラリを取得してロードするための元の方法です。デフォルトでは、マシン上のすべてのプログラムで共有される単一のグローバルパッケージキャッシュがあり、(おそらく紛らわしいことに) Quicklisp とも呼ばれる保守的に更新されたリポジトリからパッケージを取得します。

quicklisp パッケージをインストールした後、特定コンパイラに対して次のように登録できます:

> sbcl --load /usr/share/quicklisp/quicklisp.lisp
* (quicklisp-quickstart:install)
* (ql:add-to-init-file)

その後、(ql:quickload "foo") を将来のすべての REPL セッションで使用して依存関係をロードし、必要に応じてダウンロードできます。

Quicklisp を介してインストールされたすべてのパッケージを更新するには、REPL で以下を実行します:

(ql:update-all-dists)
ノート: 一般的に、Quicklisp は、作成するすべての Common Lisp プロジェクトが ~/common-lisp/ にあることを想定しています。これは、Vend や OCICL などの他の方法には当てはまりません。

Ultralisp

Ultralisp は、すべてのパッケージのローリングリリースを提供する代替の Quicklisp リポジトリであり、一般的に Github などで利用可能な最新の状態に保たれています。

登録するには、REPL で以下を実行します:

(ql-dist:install-dist "http://dist.ultralisp.org/" :prompt nil)

次に、ql:quickload を介してロードするパッケージが Ultralisp で新しい場合、Quicklisp ではなくそこからロードされます。

Qlot

あるいは、Quicklisp で問題ないが、プロジェクトローカルの依存関係が必要な場合は、Qlot (qlotAUR) を使用できます。

インストール後、プロジェクトリポジトリは次のように初期化して使用できます:

qlot init

カスタム依存関係

Qlot では、すべてのカスタム依存関係の場所は qlfile 内で宣言されます。たとえば、Ultralisp の使用を宣言するには、次を追加します:

dist http://dist.ultralisp.org

または、ローカルファイルシステムの依存関係を指定するには、次のようにします:

local foobar /home/you/code/common-lisp/foobar

その他のオプションについては、Qlot の README を参照してください。

宣言された依存関係をインストールするには、次を実行します。

qlot install

REPL の起動

現在の Qlot 環境で REPL をロードするには、次を実行します:

qlot exec sbcl

Sly/Slime の Emacs ユーザーは、エディタ内 REPL の起動方法を次のように設定することを検討してください:

(setq sly-default-lisp 'qlot-sbcl
      sly-lisp-implementations '((qlot-sbcl ("qlot" "exec" "sbcl") :coding-system utf-8-unix)))

Slime に合わせて必要に応じて調整してください。

開発環境

Emacs

Common Lisp の開発は、多くの場合、slime または新しい sly を介して Emacs で行われます。どちらもコミュニティで広く採用されており、同様の使用インターフェースを備えています。

Portacle

Portacle は、Common Lisp 開発用の Emacs ベースのオールインワン環境です。その目的は、初心者を簡単に Lisp に導入することです。

Lem

Lem (lem-editor-gitAUR) は、Emacs スタイルの新しいエディタですが、Common Lisp で完全に記述および設定されています。ターミナルと GUI フロントエンドがあり、多くの言語をサポートしています。

Vim

Slimv は、Emacs の Slime の移植版であり、Slime の Swank バックエンドサーバーを利用して、Emacs と非常に似たエクスペリエンスを提供します。プラグインを手動でインストールするには、次のようにします:

mkdir -p ~/.vim/pack/common-lisp/start
cd ~/.vim/pack/common-lisp/start
git clone --depth 1 https://github.com/kovisoft/slimv.git

Vim を再起動し、Common Lisp ファイルを開きます。Slimv がアクティブになり、,c が REPL サーバーを起動し、接続します。

VSCode

VSCode での Common Lisp のサポートはエディタの中で最も弱いですが、それでも可能です。Alive プラグインは、独自の LSP とともに完全な開発環境として機能し、手動インストールが必要です。

ヒント

初期化ファイルの管理

ライブラリの作成者は、多くの場合、複数のコンパイラ実装でコードをテストします。ただし、各実装には .sbclrc.eclrc など、固有の名前の初期化ファイルがありますが、これらのファイルの内容は多くの場合同じです。各コンパイラに対してこれらのファイルを手書きするのではなく、1 つのマスターファイルを作成し、他のファイルをそれにシンボリックリンクできます。たとえば、.sbclrc を「マスター設定」と見なす場合、次のようになります:

ln -s /home/you/.sbclrc .eclrc
ln -s /home/you/.sbclrc .abclrc

など。主な初期化ファイルは次のとおりです:

~/.sbclrc          # for SBCL
~/.abclrc          # for ABCL
~/.ccl-init.lisp   # for CCL
~/.clasprc         # for CLASP
~/.eclrc           # for ECL
~/.clisprc.lisp    # for CLISP
~/.cmucl-init.lisp # for CMUCL
~/.mkclrc          # for MKCL
~/.clinit.cl       # for Allegro

詳細でないコンパイル出力

特に SBCL は、出力するコンパイラ "ノート" の数に非常に熱心になる可能性があります。通常のエラーと警告を表示しながらこれらのノートを抑制するには、~/.sbclrc に以下を設定します:

(declaim (sb-ext:muffle-conditions sb-ext:compiler-note))

トラブルシューティング

Quicklisp がローカルプロジェクトをロードできない

(ql:quickload "...") は、外部依存関係とローカルプロジェクトの両方をロードするために使用されます。ただし、ローカルプロジェクトが ~/common-lisp/ にない場合、ロードに失敗します (または、公開している場合はオンラインからプルされる可能性もあります)

実際には、Quicklisp はパッケージを取得して整理しているだけです。内部的には、ASDF ビルドシステムを使用して実際にロードします。(asdf:load-system "foo") を介してローカルプロジェクトまたは既にダウンロードしたパッケージをロードすることもできます。デフォルトでは、ASDF はローカルプロジェクトに対して ~/common-lisp/ のみを検索します。

設定可能ですが、より簡単な回避策はシンボリックリンクを使用することです:

ln -s /home/you/code/common-lisp/ common-lisp
ノート: Vend、OCICL、または Qlot を使用している場合、上記のシンボリックリンクは必要ありません。正しく設定されていれば、(asdf:load-package "foo") は "そのまま動作" します。

プロジェクト、システム、パッケージとは何ですか?

この記事の残りの部分では、"パッケージ" という用語は、他のプログラミング言語で通常使用されるように、"ライブラリ" と同義で使用されています。ただし、90 年代半ばに標準化されましたが、Common Lisp の初期の形式は 80 年代に遡るため、プロジェクト管理に関連する用語は異なります。要するに:

  • プロジェクト: システムのグループ。他の言語では "ワークスペース" と呼ばれることもあります。
  • システム: パッケージのグループ。これらはライブラリと "実行可能ファイル" の両方を表すことができます。
  • パッケージ: 関数と型定義のグループ。他の言語では "モジュール" と呼ばれることが多いですが、複数のファイルにまたがる場合があります。

ご覧のとおり、他の場所で通常ライブラリと呼ばれるものは、Common Lisp では "システム" と呼ばれます。したがって、asdf:load-system という名前になります。相互依存するマルチシステムプロジェクトの例については、こちら を参照してください。

参照