付録
−−− 詳細ノード一覧 −−−
以下は、上にあげたノードの下位ノードです。 直接移動できるように掲載しておきます。
導入
慣習
nil and t are used.
ヒントと慣習
記述形式
Lispデータ型
プログラミング向けの型
リスト型
編集向けの型
数
文字列と文字
format: Emacs's analogue of printf.
リスト
既存リスト構造の変更
シーケンス、配列、ベクトル
シンボル
評価
フォームの種類
制御構造
if, cond.
and, or, not.
while loops.
非ローカル脱出
エラー
変数
スコープルールと変数束縛
バッファローカルな変数
関数
ラムダ式
マクロ
ロード
load function and others.
バイトコンパイル
関数のアドバイス
defadvice.
defadvice as fset is to defun.
Lispプログラムのデバッグ
Lispデバッガ
debug.
不正なLisp構文のデバッグ
Lispオブジェクトの読み取りと表示
ミニバッファ
補完
コマンドループ
コマンドの定義
interactive.
キーマップ
メジャーモードとマイナモード
メジャーモード
マイナモード
モード行の書式
説明文
ファイル
ファイルを訪問する
ファイルに関する情報
ファイル名
バックアップと自動保存
revert-buffer, and how to customize
what it does.
バックアップファイル
バッファ
ウィンドウ
フレーム
バッファ内の位置
移動
マーカ
テキスト
キルリング
字下げ
テキスト属性
探索と一致
正規表現
構文テーブル
構文記述子
略語と略語の展開
プロセス
プロセスからの出力を受け取る
オペレーティングシステムとのインターフェイス
Emacsの始動
.emacs).
Emacsから抜ける
Emacsの画面表示
GNU Emacsの内部
オブジェクトの内部
1991年6月 バージョン2.0
Copyright © 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA 1 何人も、以下の内容を変更しないでそのまま複写する場合に限り、 本使用許諾書を複製したり頒布することができます。
ほとんどのソフトウェアの使用許諾は、ソフトウェアを共有し、 変更するユーザの自由を奪うことを意図しています。 それに対して、我々のGNU一般公有使用許諾は、 フリー・ソフトウェアを共有したり変更する自由をユーザに保証するためのもの、 即ちフリー・ソフトウェアがそのユーザ全てにとって フリーであることを保証するためのものです。 本使用許諾は、Free Software Foundationのほとんど全てのソフトウェアに 適用されるだけでなく、 プログラムの作成者が本使用許諾に依るとした場合のそのプログラムにも 適用することができます。 (その他の Free Software Foundation のソフトウェアのいくつかは、 本許諾書ではなく、GNUライブラリ一般公有使用許諾で保護されます。) あなたは自分のプログラムにもこれを適用できます。
我々がフリー・ソフトウェアについて言う場合は 自由のことに言及しているのであって、価格のことではありません。 我々の一般公有使用許諾の各条項は、次の事柄を確実に実現することを 目的として立案されています。
このようなユーザの権利を守るために、我々は、 何人もこれらの権利を否定したり、あるいは放棄するように ユーザに求めることはできないという制限条項を設ける必要があります。 これらの制限条項は、ユーザが、フリー・ソフトウェアの複製物を 頒布したり変更しようとする場合には、そのユーザ自身が守るべき義務ともなります。
例えば、あなたがフリー・ソフトウェアの複製物を頒布する場合、 有償か無償かにかかわらず、 あなたは自分の持っている権利を全て相手に与えなければなりません。 あなたは、相手もまたソース・コードを受け取ったり入手できるということを 認めなければなりません。 さらにあなたは、彼らが自分たちの権利を知るように、 これらの条項を知らしめなければなりません。
我々は次の2つの方法でユーザの権利を守ります。 (1)ソフトウェアに著作権を主張し、 (2)本使用許諾の条項の下で ソフトウェアを複製・頒布・変更する権利をユーザに与えます。
また、各作成者や我々自身を守るために、 本フリー・ソフトウェアが無保証であることを 全ての人々が了解している必要があります。 さらに、他の誰かによって変更されたソフトウェアが頒布された場合、 受領者はそのソフトウェアがオリジナル・バージョンではないということを 知らされる必要があります。 それは、他人の関与によって原開発者に対する評価が 影響されないようにするためです。
最後に、どのフリー・プログラムもソフトウェア特許に絶えず脅かされています。 我々は、フリー・プログラムの再頒布者が個人的に特許権を取得し、 事実上そのプログラムを自分の財産にしてしまうという危険を 避けたいと願っています。 これを防ぐために我々は、いずれの特許も、 誰でも自由に使用できるように使用許諾されるべきか、 あるいは何人に対しても全く使用させないかの、 いずれかにすべきであることを明らかにしてきました。
複写・頒布・変更に対する正確な条項と条件を次に示します。
複製、頒布、変更以外の行為は本使用許諾の対象としません。 それらは本使用許諾の範囲外です。 「プログラム」を実行させる行為に関して制約はありません。 「プログラム」の出力は、 (「プログラム」を実行させて作成させたかどうかとは無関係に) その内容が「プログラム生成物」である場合に限り本使用許諾の対象となります。 これが当てはまるかどうかは、「プログラム」が何をするものかに依ります。
複製物の引き渡しに要する実費は請求することができます。 また、あなた独自の保証を行なう場合はそれを有償とすることができます。
これらの要件は変更された作成物にも全て適用されます。 その変更版の或る部分が「プログラム」の派生物ではなく、 しかもそれ自体独立で異なる作成物だと合理的に考えられる場合、 あなたがそれらを別の作成物として頒布した時は、 本使用許諾とその条項はそれらの部分には適用されません。 しかし、それらを「プログラム生成物」の一部として頒布する場合は、 全体が本使用許諾の条項に従って頒布されなければならず、 使用許諾を受ける他の全ての者に対する許諾も プログラム全体にわたって与えられなければならず、 結果として、誰が書いたかにかかわらず、 全ての部分に本使用許諾が適用されなければなりません。
このように、本条項の意図するところは、 完全にあなたによって書かれた作成物について、権利を要求したり、 あなたと権利関係を争うことではありません。 むしろその目的は、作成物が「プログラム生成物」 である場合にその派生物や集合物の頒布を規制することにあります。
さらに、「プログラム」(又は「プログラム生成物」)と 「プログラム生成物」とはならない他のプログラムとを、 単に保管や頒布のために同一の媒体上にまとめて記録したとしても、 本使用許諾は他のプログラムには適用されません。
なお、ソース・コードとは、変更作業に適した記述形式を指します。 また、実行可能形式のファイルに対応するソース・コード一式とは、 それに含まれる全モジュールに対応する全てのソース・コード、 及びあらゆる関連のインタフェース定義ファイル、 及び実行を可能にするコンパイルとインストールの制御に関する記述を指します。 特別な例外として、実行可能なファイルが動作するオペレーティング・システムの 主要な構成要素(コンパイラ、カーネルなど)と共に (ソース・コード又はバイナリのどちらかで)頒布されているものについては、 その構成要素自体が実行形式に付随していない場合に限り、 頒布されるソース・コードに含める必要はありません。
実行可能形式またはオブジェクト・コードの頒布が、 指示された場所からの複製のためのアクセス権の賦与である場合、 同じ場所からのソース・コードの複製のための同等なアクセス権を賦与すれば、 たとえ第三者にオブジェクト・コードと共にソースの複製を強いなくとも、 ソース・コードを頒布したものとみなします。
本条項の或る部分が何らかの特別な状況下で無効または適用不可能になった場合、 本条項のその他の残りの部分が適用されるように意図されており、また、 本条項は全体としてその他の状況に当てはまるように意図されています。
本条項の目的は、特許やその他の財産権を侵害したり、 そのような権利に基づく主張の妥当性を争うようにあなたに 勧めることではありません。 本条項の唯一の目的は、フリー・ソフトウェアの頒布システムの完全性を守ることで、 それは公有使用許諾の実践によって履行されます。 多くの人々が、このシステムの一貫した適用を信頼して、 このシステムを通じて頒布されている幅広い範囲のソフトウェアに惜しみない貢献を してくれました。 作成者や寄贈者が他の何らかのシステムを通じてソフトウェアを 頒布したいと決めることは彼らの自由意志であり、 使用許諾を受ける者はその選択を強いることはできません。
本条項は、本使用許諾の他の条項の意味内容が何であるかを 完全に明らかにすることを意図しています。
各バージョンは、バージョン番号によって区別します。 「プログラム」中に本使用許諾のバージョン番号の指定がある場合は、 その指定されたバージョンか、又はその後にFree Software Foundationから 公表されているいずれかのバージョンから1つを選択して、 その条項と条件に従ってください。 「プログラム」中に本使用許諾のバージョン番号の指定がない場合は、 Free Software Foundation が公表したどのバージョンでも選択することができます。
英文文書(GNU General Public License)を正式文書とする。 この和文文書は弁護士の意見を採り入れて、 できるだけ正確に英文文書を翻訳したものであるが、 法律的に有効な契約書ではない。
いかなる媒体でも次の条件がすべて満たされている場合に限り、 本和文文書をそのまま複写し配布することを許可する。 また、あなたは第三者に対して本許可告知と同一の許可を与える場合に限り、 再配布することが許可されています。
あなたが新しくプログラムを作成し、それを公用に供したい場合は、 プログラムをフリー・ソフトウェアにして、 全ての人々が以上の各条項に従ってこれを再頒布や変更をすることが できるようにするのが最良の方法です。
そうするためには、プログラムに以下の表示をしてください。 その場合、無保証であるということを最も効果的に伝えるために、 ソース・ファイルの冒頭にその全文を表示すれば最も安全ですが、 その他の方法で表示する場合でも、「著作権表示」と全文を読み出す為の アドレスへのポインタだけはファイル上に表示しておいてください。
プログラム名とどんな動作をするものかについての簡単な説明の行 Copyright(C) 19○○年、著作権者名 本プログラムはフリー・ソフトウェアです。 あなたは、Free Software Foundationが公表したGNU 一般公有使用許諾の 「バージョン2」或いはそれ以降の各バージョンの中からいずれかを選択し、 そのバージョンが定める条項に従って本プログラムを 再頒布または変更することができます。 本プログラムは有用とは思いますが、頒布にあたっては、 市場性及び特定目的適合性についての暗黙の保証を含めて、 いかなる保証も行ないません。 詳細についてはGNU 一般公有使用許諾書をお読みください。 あなたは、本プログラムと一緒にGNU一般公有使用許諾の写しを 受け取っているはずです。 そうでない場合は、
Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA 2 へ手紙を書いてください。
また、ユーザが電子メイルや書信であなたと連絡をとる方法についての情報も 書き添えてください。
プログラムが対話的に動作する場合は、 対話モードで起動した時に次のような短い告知文が表示されるようにしてください。
Gnomovision バージョン69、Copyright(C)19○○年 著作権者名 Gnomovision は完全に無保証です。詳細は show w とタイプしてください。 これはフリー・ソフトウェアなので、特定の条件の下でこれを再頒布する ことができます。詳細は show c とタイプしてください。
上記のshow wやshow cは各々、
本一般公有使用許諾の関連する部分を表示するコマンドを指します。
もちろん、あなたが使うこれらのコマンドはshow wやshow cといった
呼び名でなくても構いません。
さらに、それらのコマンドはあなたのプログラムに合わせる為に、
マウスでクリックしたりメニュー形式にすることもできます。
また、必要と認めた場合には、あなたの雇い主 (あなたがプログラマとして働いている場合)や在籍する学校から、 そのプログラムに対する「著作権放棄」を認めた署名入りの書面を入手してください。 ここにその文例を載せます。名前は変えてください。
Yoyodyne, Inc. は、James Hacker が開発したプログラム`Gnomovision' (コンパイラにつなげるプログラム)についての著作権法上の全ての権利を放棄する。 Ty Coon の署名, 1 April 1989 Ty Coon, 副社長
本一般公有使用許諾は、あなたのプログラムを財産権の対象となっている 他のプログラムに組み込むことは認めていません。 あなたのプログラムがサブルーチン・ライブラリであって、 あなたがそのライブラリを財産権の対象となっている他のアプリケーションと リンクさせることによって、さらに有用なものにしようとする場合には、 本使用許諾書の代わりに、GNUライブラリ一般公有使用許諾書に従ってください。
GNU Emacsテキストエディタの大部分は、 Emacs Lispと呼ばれるプログラム言語で記述してあります。 Emacs Lispで新たなコードを書いて、 それをエディタの拡張としてインストールできます。 しかし、Emacs Lispは、単なる『拡張言語』ではありません。 それ自身、れっきとしたプログラム言語です。 他のプログラム言語でできることは、Emacs Lispでできます。
Emacs Lispは、エディタで使うために設計してあるため、 ファイル、バッファ、ディスプレイ、サブプロセスなどを扱う機能に加えて、 テキストを走査し解析する特別な機能もあります。 Emacs Lispは編集機構に密に組み込まれています。 このため、編集コマンドはLispプログラムからも呼び出せる関数ですし、 カスタマイズのためのパラメータは普通のLisp変数です。
本書は、Emacs Lispを完全に記述することを目指しています。 初心者向けの入門には、Free Software Foundation刊、 Bob ChassellのAn Introduction to Emacs Lisp Programming 3 をご覧ください。 本書では、Emacsの操作を熟知しているものと仮定します。 操作に関する基本的な情報は、The GNU Emacs Manual 4 を参照してください。
おおまかにいえば、始めのほうの章では、 多くのプログラム言語に見られる機能に相当するEmacs Lispの機能を説明し、 あとのほうの章では、 Emacs Lispに特有の機能や編集に特化した機能を説明します。
本書は、2.5版です。
本書は、数多くの草稿を重ねてきました。 ほぼ完璧に近いはずですが、誤りは皆無ではありません。 ふれていない話題も少なからずあります。 (大部分の個別のモードのような)副次的と捉えている話題や、 まだ執筆していない話題もあります。 完全にはこれらに対処しきれませんので、 意図的に省いたことがらもあります。 たとえば、VMSにおける利用方法に関する情報です。
本書で取り上げたことがらに関しては、本書は完璧であるべきですから、 例題や記述内容から章や節の構成順序といったことまで、 広く意見を求めています。 混乱を招くような記述や、本書でふれていないことがらを 学ぶためにソースや実験で調べる必要があるときには、 本書を改訂すべきなのでしょう。 そのときは、ぜひ、教えてください。
意見や訂正は、下記へメイルしてください。
bug-lisp-manual@gnu.org
ここに蓄積されたメイルは、誰かが改訂作業を始めるまでは、読み出しません。
改訂までに、数か月、ときには、数年経過することもあります。
ですから、返事がないと憤慨しないでください。
あなたのメイルは、そのうち処理されます。
Emacs保守グループに迅速に連絡したい場合には、
bug-gnu-emacs@gnu.orgにメイルしてください。
Lisp(LISt Processing language、リスト処理言語)は、 人工知能の研究向けに1950年代末にMITで初めて開発されました。 Lisp言語はとても強力なので、 エディタコマンドを記述するなどの他の目的にも理想的なのです。
長年にわたって何ダースものLispが実装されており、 それぞれが独自の特徴を有しています。 その多くは、1960年代のMITのMACプロジェクトで開発されたMaclispの 影響を受けています。 最終的には、Maclispの系統の実装者達は共同して、 Common Lispと呼ばれるLispシステムの規格を開発しました。 そうこうするうちに、MITのGerry SussmanとGuy Steeleは、 単純化してあるが非常に強力なSchemeと呼ばれるLispの方言を開発しました。
GNU EmacsはMaclispの影響を強く受けていますが、 Common Lispからの影響は少ないです。 Common Lispを知っている読者は、 Common Lispとの多くの類似点に気づかれるでしょう。 しかしながら、Common Lispの多くの機能は、 省いてあるか、単純化してあります。 これは、GNU Emacsが必要とするメモリ量を削減するためです。 ときには、劇的に単純化してあるために、 Common Lispユーザーは混乱するかもしれません。 GNU Emacs LispとCommon Lispとの相違点は、 ことあるごとに指摘するつもりです。 Common Lispを知らない読者は、何も心配することはありません。 本書は自己完結しています。
clライブラリにより、Common Lispをかなりエミュレートできます。
See Top。
Emacs LispはSchemeの影響をまったく受けていません。 しかし、GNUプロジェクトには、Guileと呼ばれるSchemeの実装があります。 拡張が必要なすべての新たなGNUソフトウェアではGuileを使います。
本節では、本書で用いる表記法を説明します。 本節を読み飛ばして、あとで参照してもかまいません。
nil and t are used.
本書では、『Lispリーダ』および『Lispプリンタ』という言葉で、 Lispオブジェクトのテキスト表現を実際のLispオブジェクトに変換する Lisp内部のルーティン群、および、逆の変換を行うルーティン群を指します。 詳しくは、See Printed Representation。 本書の読者を『プログラマ』と考えて『読者』と呼びます。 『ユーザー』とは作者自身を含めたLispプログラムを使う人のことです。
Lispコードの例は、(list 1 2 3)という形式で、
このフォントで記します。
メタな変数の名前や説明対象の関数に対する引数の名前は、
first-numberという形式で、このフォントで書きます。
nilとtLispでは、シンボルnilには3つの異なる意味があります。
まず、nilという名前のシンボルです。
2つめは、真理値の偽(false)です。
3つめは、空リスト、つまり、要素数が0個のリストです。
変数として使った場合、nilの値はつねにnilです。
Lispリーダにとっては、()とnilは同一です。
どちらも、同じオブジェクト、シンボルnilを表します。
シンボルを異なった書き方にするのは、完全に人間向けです。
()やnilをLispリーダが読み取ったあとでは、
プログラマが実際にどちらの表記を用いたかわかりません。
本書では、空リストを強調するときには()を使い、
真理値の偽を強調するときにはnilを使います。
これは、Lispプログラムでも使うとよい慣習です。
(cons 'foo ()) ; 空リストであることを強調する (not nil) ; 真理値の偽であることを強調する
真理値の真を必要とする場面では、
nil以外の値は、真(true)であるとみなします。
しかし、真を表す望ましい書き方はtです。
真を表す値が必要なとき、
適当な判断基準がない場合にはtを使います。
シンボルtの値はつねにtです。
Emacs Lispでは、nilとtは特別なシンボルであり、
評価するとそれ自身になります。
そのため、これらをプログラム内で定数として使うとき、
これらをクォートする必要はありません。
これらの値を変更しようとすると、エラーsetting-constantになります。
コロン(:)で始まる名前のシンボルも同様です。
See Constant Variables。
評価可能なLisp式をフォーム(form、形式)と呼びます。
フォームを評価すると、Lispオブジェクトである結果を生じます。
本書の例題では、これを=>で表します。
(car '(1 2))
=> 1
これは、『(car '(1 2))を評価すると1になる』と読みます。
フォームがマクロ呼び出しの場合には、
Lispが評価すべき新たなフォームに展開します。
展開結果を==>で表します。
展開したフォームの評価結果を示す場合もあれば、
示さない場合もあります。
(third '(a b c))
==> (car (cdr (cdr '(a b c))))
=> c
あるフォームを説明するときに、
同一の結果を生じる別のフォームを示すことがあります。
2つのまったく等価なフォームを==で表します。
(make-sparse-keymap) == (list 'keymap)
本書の数多くの例題は、評価するとテキストを表示します。
(*scratch*バッファのような)Lisp対話バッファで例題のコードを
実行すると、表示テキストはバッファに挿入されます。
(関数eval-regionで評価するなどの)
別の手段で例題を実行すると、表示テキストはエコー領域に表示されます。
エコー領域に表示されるテキストは、1行に切り詰められていることに
注意してください。
本書の例題では、表示場所には無関係に、
表示テキストを-|で表します。
フォームを評価した結果返される値(ここではbar)は、
後続の行に分けて書きます。
(progn (print 'foo) (print 'bar))
-| foo
-| bar
=> bar
エラーを通知する例題もあります。
これは、通常、エコー領域にエラーメッセージを表示します。
エラーメッセージは、error-->で始まる行に示します。
エコー領域には、error-->は表示されないことに注意してください。
(+ 23 'x) error--> Wrong type argument: number-or-marker-p, x
バッファ内のテキストを修正する例題もあります。
このような場合、『実行前』と『実行後』のテキストを示します。
それらの例題では、バッファ名を含めたダッシュから成る2行で挟んで、
当該バッファの内容を示します。
さらに、ポイント位置を-!-で表します。
(もちろん、ポイントを表す記号は、バッファ内のテキストの一部ではない。
現在ポイントが位置する2つの文字のあいだを表す。)
---------- Buffer: foo ----------
This is the -!-contents of foo.
---------- Buffer: foo ----------
(insert "changed ")
=> nil
---------- Buffer: foo ----------
This is the changed -!-contents of foo.
---------- Buffer: foo ----------
関数、変数、マクロ、コマンド、ユーザーオプション、 スペシャルフォームは、本書では統一した形式で記述します。 第1行目は、それぞれの名前と、引数があれば引数群です。 これに説明文が続き、場合によっては例題も示します。
foo.
electric-future-map.
関数の記述では、まず始めに説明対象の関数名があります。 同じ行には、引数名の並びも続きます。 これらの名前は、説明文の中で引数の値を参照するために使います。
引数ならびにキーワード&optionalが現れていれば、
それ以降の引数を省略できることを示します(省略した引数の値はnil)。
関数を呼び出すときに&optionalを書いてはいけません。
キーワード&rest (このあとには1つの引数名だけが続く)は、
残りの引数が何個でもよいことを示します。
直後にある1つの引数名は、変数としての値を持ち、
その値は残りのすべての引数のリストです。
関数を呼び出すときに&restを書いてはいけません。
では、仮想的な関数fooの記述を以下に示します。
| foo integer1 &optional integer2 &rest integers | Function |
関数fooは、integer2からinteger1を引き算し、
残りのすべての引数を減算結果に加える。
integer2を指定しないと、デフォルトでは、数19から引き算する。
(foo 1 5 3 9)
=> 16
(foo 5)
=> 14
より一般的には、つぎのとおり。 (foo w x y...) == (+ (- x w) y...) |
(integer、integer1、bufferなどの)型名を名前とする引数は、 その型の値であると仮定します。 (buffersのように)型を複数形にした場合には、 しばしば、その型のオブジェクトのリストを意味します。 objectという名前の引数は、任意の型でかまいません。 (Emacsオブジェクトの型の一覧については、see Lisp Data Types)。 (new-fileなどの)その他の名前の引数は、関数の説明文の中で言及します。 複数の関数の引数に共通する特徴について、 節の始めで説明する場合もあります。
&optionalと&restについての詳しい説明は、
See Lambda Expressions。
コマンド、マクロ、スペシャルフォームの記述も同じ形式ですが、 「関数」のかわりに 「コマンド」、「マクロ」、「スペシャルフォーム」のいずれかです。 コマンドは、対話的に呼び出せる単なる関数です。 マクロは関数とは違った方法で引数を処理します(引数を評価しない)が、 同じ方法で引数を記します。
スペシャルフォームの記述では、省略可能な引数や繰り返される引数を
示すために、より複雑な記法を使います。
というのは、引数並びを個々の引数に分離する方法が複雑だからです。
[optional-arg]は、
optional-argが省略可能であることを示します。
また、repeated-args...は、0個以上の引数を示します。
いくつかの引数をリスト構造の内側にまとめるときには、
括弧を使います。
| count-loop (var [from to [inc]]) body... | Special Form |
この仮想的なスペシャルフォームは、
フォーム群bodyを実行してから変数varを増やすことを
反復するループを実現する。
最初は、変数の値はfromである。
以降の反復では、変数を1(あるいは、指定があればincだけ)増やす。
varがtoに等しくなると、
bodyを実行せずにループから抜ける。
例を示す。
(count-loop (i 0 10) (prin1 i) (princ " ") (prin1 (aref vector i)) (terpri)) fromとtoを省略すると、
ループ開始前にvarに (count-loop (done)
(if (pending)
(fixit)
(setq done t)))
このスペシャルフォームでは、引数fromとtoは省略できるが、 両者を同時に指定するか、同時に省略すること。 これらを指定した場合、incを指定してもよい。 これらの引数は、引数varとともにリストにまとめる。 これはbodyと区別するためであり、 bodyは残りのフォームの要素すべてを含む。 |
変数(variable)は、値を保持するための名前です。 ユーザーはどんな変数でも設定できますが、 ユーザーが変更可能な特定の変数群があり、 それらをユーザーオプション(user options)と呼びます。 普通の変数もユーザーオプションも関数の記述と同じ形式で示しますが、 それらに引数はありません。
仮想的な変数electric-future-mapの記述例を示します。
| electric-future-map | Variable |
| この変数の値は、Electric Command Futureモードで使用する 完全なキーマップである。 このマップに含まれる関数は、まだ実行していないコマンドの編集を可能にする。 |
ユーザーオプションの記述も同じ形式ですが、 「変数」のかわりに「ユーザーオプション」です。
これらの機構は、使用中のEmacsの版に関する情報を提供します。
| emacs-version | コマンド |
この関数は、実行中のEmacsの版を記述した文字列を返す。
この文字列はバグの報告に含めると有益である。
(emacs-version) => "GNU Emacs 20.3.5 (i486-pc-linux-gnulibc1, X toolkit) of Sat Feb 14 1998 on psilocin.gnu.org" 対話的に呼び出すと、この関数は同じ情報をエコー領域に表示する。 |
| emacs-build-time | Variable |
この変数の値は、ローカルのサイトでEmacsを構築した日時を示す。
3つの整数から成るリストであり、
current-timeと同様のもの(see Time of Day)。
emacs-build-time
=> (13623 62065 344633)
|
| emacs-version | Variable |
この変数の値は、実行中のEmacsの版番号。
"20.3.1"のような文字列である。
この文字列の最後の数字は、Emacsのリリース版番号の一部ではなく、
特定のディレクトリでEmacsを構築するたびに増える。
|
つぎの2つの変数は、Emacs 19.23以降に存在します。
| emacs-major-version | Variable |
| Emacsのメジャー版番号を表す整数。 Emacs 20.3では、値は20。 |
| emacs-minor-version | Variable |
| Emacsのマイナ版番号を表す整数。 Emacs 20.3では、値は3。 |
本書は、Robert Krawitz、Bil Lewis、Dan LaLiberte、 Richard M. Stallman、Chris Welty、GNUマニュアルプロジェクトのボランティア による何年にもわたる努力で執筆されました。 Computational Logic社のWarren A. Hunt, Jr.が手配した 国防省Advanced Research Projects Agency、ARPA Order 6082の援助のもと、 Robert J. Chassellは本書のレビューと編集に協力してくれました。
以下の方々が訂正を送ってくれました。 Karl Berry、Jim Blandy、Bard Bloom、 Stephane Boucher、David Boyes、Alan Carroll、Richard Davis、Lawrence R. Dodd、Peter Doornbosch、David A. Duff、Chris Eich、Beverly Erlebacher、David Eckelkamp、Ralf Fassel、Eirik Fuller、Stephen Gildea、 Bob Glickstein、Eric Hanchrow、George Hartzell、Nathan Hess、 Masayuki Ida、 Dan Jacobson、Jak Kirman、Bob Knighten、Frederick M. Korz、Joe Lammens、Glenn M. Lewis、K. Richard Magill、Brian Marick、Roland McGrath、Skip Montanaro、John Gardiner Myers、Thomas A. Peterson、 Francesco Potorti、Friedrich Pukelsheim、Arnold D. Robbins、Raul Rockwell、Per Starback、Shinichirou Sugou、Kimmo Suominen、Edward Tharp、 Bill Trost、Rickard Westman、Jean White、Matthew Wilding、Carl Witty、 Dale Worley、Rusty Wright、David D. Zuhn。
Lispオブジェクト(object)とは、 Lispプログラムが使用し操作するデータのことです。 型(type)やデータ型(data type)とは、ここでは、 可能なオブジェクトの集合を意味します。
各オブジェクトは、少なくとも、1つの型に属します。 同じ型のオブジェクトは、構造に類似性があり、普通、同じ文脈で使われます。 型は互いに重複していてもよく、オブジェクトは複数の型に属することができます。 そのため、オブジェクトが特定の型に属するかどうかは判断できますが、 オブジェクトの型を『1つ』に限定することはできません。
Emacsには少数の基本オブジェクト型を組み込んであります。 これらの型は他のすべてのオブジェクト型を構成するもとであり、 基本型(primitive types)と呼びます。 各オブジェクトはたった1つの基本型に属します。 基本型には、 整数(integer)、浮動小数点数(float)、 コンス(cons)、シンボル(symbol)、 文字列(string)、ベクトル(vector)、subr、 バイトコード関数(byte-code function)、 ならびに、編集に関連するバッファ(buffer)などの 特別な型があります。 (see Editing Types。)
各基本型には、その型に属するオブジェクトであるかどうかを検査する 対応するLisp関数があります。
Lispオブジェクトは型を自己記述(self-typing)するという点で、 Lispは他の多くの言語とは異なります。 つまり、オブジェクトの基本型は、オブジェクト自体に暗に含まれています。 たとえば、オブジェクトがベクトルであれば、それを数と扱うことはありません。 Lispには、ベクトルは数ではないとわかっているのです。
多くの言語では、プログラマは各変数のデータ型を宣言する必要があります。 型はコンパイラが知っているのであって、データの中には入っていません。 このような型宣言はEmacs Lispには存在しません。 Lisp変数はどんな型の値でも保持でき、 変数に入れた値と型を記録しています。
本章では、GNU Emacs Lispの各標準型の表示表現と入力構文を説明します。 これらの型の使用方法の詳細は、あとの章に譲ります。
オブジェクトの表示表現(printed representation)とは、
Lispプリンタ(関数prin1)がそのオブジェクトを出力表示するときの
書式です。
オブジェクトの入力構文(read syntax)とは、
Lispリーダ(関数read)がそのオブジェクトを入力として受理する書式です。
See Read and Print。
ほとんどのオブジェクトには1つ以上の可能な入力構文があります。 ある種の型のオブジェクトには入力構文はありませんが、 そのような型のオブジェクトをLispプログラムに直接入力する意味がないからです。 このような場合を除くと、 オブジェクトの表示表現はそのオブジェクトの入力構文でもあります。
他の言語では、式はテキストであって、これ以外の形はありません。 Lispでは、式はとにかくLispオブジェクトであって、 オブジェクトの入力構文であるテキストは副次的なものです。 この違いを強調する必要はありませんが、 このことを心に留めておかないと混乱することがあります。
各型には表示表現があります。
入力構文のない型もあります。
たとえば、バッファ型には入力構文はありません。
このような型のオブジェクトはハッシュ記法(hash notation)で表示します。
つまり、文字列#<のあとに説明用の文字列
(典型的には型名にオブジェクトの名前を続けたもの)を続け、
対応する>で閉じます。
ハッシュ記法を読み取ることはできませんから、
Lispリーダが#<に出会うとエラーinvalid-read-syntaxを
通知します。
(current-buffer)
=> #<buffer objects.texi>
読者が対話的に式を評価するとき、
Lispインタープリタは、まず、
式のテキスト表現を読み取ってLispオブジェクトを生成し、
そのオブジェクトを評価します(see Evaluation)。
しかしながら、評価と読み取りは別々の動作です。
読み取りでは、読み取ったテキストが表すLispオブジェクトを返します。
このオブジェクトを、のちに評価する場合もありますが、
評価しない場合もあります。
オブジェクトを読み取る基本関数readについては、
See Input Functions。
コメント(comment)は、プログラム内に書かれたテキストであり、
プログラムを読む人間のためだけにあり、
プログラムの意味にはまったく影響しません。
Lispでは、文字列や文字定数の外にあるセミコロン(;)で
コメントを始めます。
コメントは行末までです。
Lispリーダは、コメントを破棄します。
コメントは、
Lispシステム内部でプログラムを表すLispオブジェクトの一部にはなりません。
#@countという書き方は、
後続のcount個の文字を飛び越します。
これは、プログラムで生成したバイナリデータを含むコメントに便利です。
Emacs Lispのバイトコンパイラは、出力ファイルにこのようなコメントを使います
(see Byte Compilation)。
しかしながら、ソースファイル向きではありません。
コメントの体裁に関する慣習については、See Comment Tips。
Emacs Lispには、大きく2種類の型があります。 Lispのプログラミングに関わるものと、編集に関わるものです。 前者は、さまざまな形でLispの多くの実装に見られます。 後者は、Emacs Lispに固有です。
t or nil.
Emacs Lispにおける整数の値の範囲は、ほとんどの計算機では、
-134217728から134217727(28ビット長。つまり
から
です。
(計算機によっては、より広い範囲になる。)
Emacs Lispの算術演算関数は、桁溢れ(オーバフロー)を
検査しないことを覚えておいてください。
したがって、ほとんどの計算機では、
(1+ 134217727)は-134217728となります。
整数の入力構文は、(10を基数とした)数字の並びであり、
先頭に符号があってもよく、また、最後にピリオドがあってもかまいません。
Lispインタープリタが生成する表示表現では、
先頭の+や最後の.はありません。
-1 ; 整数 -1 1 ; 整数 1 1. ; これも整数 1 +1 ; これも整数 1 268435457 ; 28ビット長整数では、これも整数 1
より詳しくは、See Numbers。
Emacsは浮動小数点数を扱えます (ただし、コンパイル時のオプションで使用不可にできる)。 浮動小数点数の範囲は、計算機に依存します。
浮動小数点数の表示表現には、
小数点(に続けて1桁以上の小数部分)または指数、
あるいは、その両方が必要です。
たとえば、1500.0、15e2、15.0e2、
1.5e3、.15e4は、同じ1500という値の
浮動小数点数を書く5つの方法です。
どれも、まったく等価です。
詳しくは、See Numbers。
Emacs Lispにおける文字(character)は、 整数以外の何物でもありません。 いいかえれば、文字はその文字コードで表現されます。 たとえば、文字Aは整数 65と表現されます。
プログラムで個々の文字を独立に使うことはあまりありません。 文字を並べた文字列(strings)として扱うことが断然多いのです。 See String Type。
文字列内、バッファ内、ファイル内の文字は、 現時点では、0から524287までの範囲、19ビット長に制限されます。 しかし、この範囲の値すべてが正しい文字コードではありません。 0から127までのコードはASCIIコードです。 それ以外は、非ASCIIです(see Non-ASCII Characters)。 キーボード入力を表す文字は、コントロール、メタ、シフトなどの 修飾キーを符号化するために、範囲がより広くなります。
文字は、実際には整数ですから、文字の表示表現は10進数です。 また、文字の入力構文として10進数も可能ですが、 Lispプログラムでこのように文字を書くのは最悪です。 Emacs Lispに用意してある文字向けの特別な入力構文を つねに使うべきです。 これらの構文は疑問符で始まります。
英数字向けの普通の入力構文は、疑問符に続けて1つの英数字を書きます。
したがって、文字Aは?A、文字Bは?B、
文字aは?aと書きます。
たとえば、つぎのとおりです。
?Q => 81 ?q => 113
同じ入力構文を句読点文字にも使えますが、
\を追加して、Lispコードを編集するEmacsコマンドが混乱しないように
することがよいでしょう。
たとえば、空白文字は?\ と書きます。
文字\は、クォートするために2つめの\を使う必要があり
?\\です。
コントロールg、バックスペース、タブ、改行、
垂直タブ、ページ送り、復帰、エスケープは、
それぞれ、?\a、?\b、?\t、?\n、?\v、
?\f、?\r、?\eと書きます。
つまり、つぎのとおりです。
?\a => 7 ; C-g ?\b => 8 ; バックスペース、 <BS>、C-h ?\t => 9 ; タブ、 <TAB>、C-i ?\n => 10 ; 改行、C-j ?\v => 11 ; 垂直タブ、C-k ?\f => 12 ; ページ送り文字、C-l ?\r => 13 ; 復帰、<RET>, C-m ?\e => 27 ; エスケープ文字、<ESC>、C-[ ?\\ => 92 ; バックスラッシュ文字、\
バックスラッシュで始まる系列は エスケープシーケンス(escape sequences)とも呼びます。 バックスラッシュが、エスケープ文字の役割を果たすからです。 この使い方は、文字<ESC>とは関係ありません。
コントロール文字は別の入力構文でも表現できます。
疑問符に続けてバックスラッシュ、カレット(^)、そして、
対応するコントロールでない文字を大文字か小文字で書きます。
たとえば、?\^Iも?\^iも、
値が9である文字C-iの正しい入力構文です。
カレットのかわりに、C-を使ってもかまいません。
ですから、?\C-iは、?\^Iや?\^iと等価です。
?\^I => 9 ?\C-I => 9
文字列やバッファ内ではASCIIのコントロール文字だけが許されますが、
キーボード入力においてはC-で任意の文字をコントロール文字にできます。
これらの非ASCIIコントロール文字の文字コードは、
対応する非コントロール文字の文字コードと
のビットを含みます。
普通の端末では、非ASCIIコントロール文字を生成する手立てはありませんが、
Xウィンドウシステムや他のウィンドウシステムでは、
簡単に生成できます。
歴史的な理由で、 Emacsは<DEL>文字を?に対応したコントロール文字として扱います。
?\^? => 127 ?\C-? => 127
その結果、今のところ、
Xウィンドウシステムのもとでは意味のある文字Control-?を
\C-では表現できません。
ファイルや文字列に現れるコントロール文字を表現するには、
^構文を勧めます。
キーボード入力のコントロール文字には、C-構文が好ましいです。
どちらを使ってもプログラムの意味には影響しませんが、
それを読む人には理解の手助けになるかもしれません。
メタ文字(meta character)は、 <META>修飾キーを使って打った文字です。 そのような文字を表す整数は、(ほとんどの計算機では負の数になる) のビットがセットされています。 上位のビットをメタや他の修飾子に用いることで、 基本となる文字コードの範囲をできるだけ大きくします。
文字列では、メタ文字を表すASCII文字には のビットを付加します。 つまり、文字列に収められるメタ文字のコードは128から255の範囲であり、 任意のASCII文字のメタ変種を使えます。 (Emacs 18やそれ以前では、この方式を文字列の外にある文字にも使っていた。)
メタ文字の入力構文には\M-を使います。
たとえば、?\M-AはM-Aです。
\M-と一緒に8進文字コードも使えますし(下記参照)、
\C-や文字向けの他の構文も使えます。
したがって、M-Aは?\M-Aと書いたり?\M-\101と書けます。
同様に、C-M-bは?\M-\C-b、
?\C-\M-b、?\M-\002と書けます。
図形文字の大文字小文字は、その文字コードで示されます。
たとえば、ASCIIではaとAの文字を区別します。
しかし、ASCIIではコントロール文字の大文字小文字を表現できません。
Emacsでは、コントロール文字を打つときに使ったシフトキーを表すために
のビットを付加します。
このような区別はX端末や他の特別な端末を使っている場合に限り可能です。
普通の端末ではこのような区別を計算機に送れません。
Xウィンドウシステムでは、
文字に設定可能な修飾ビットが他に3つあります。
ハイパー(hyper)、スーパー(super)、アルト(alt)です。
これらの修飾ビットの構文は、
\H-、\s-、\A-です。
(これらのプレフィックスでは、大文字小文字を区別する。)
したがって、?\H-\M-\A-xはAlt-Hyper-Meta-xを表します。
文字向けのもっとも汎用の入力構文では、
文字コードを8進数や16進数で表現します。
8進数を使うには、順に、
疑問符、バックスラッシュ、(3桁までの)8進数字文字コードを書きます。
たとえば、?\101は文字Aを表し、
?\001は文字C-aを表し、?\002は文字C-bを表します。
この構文で任意のASCII文字を表現できますが、
ASCIIでの表現よりも8進数値で表現することが重要な場合に限るべきです。
?\012 => 10 ?\n => 10 ?\C-j => 10 ?\101 => 65 ?A => 65
16進数を使うには、順に、疑問符、バックスラッシュ、
x、16進数字文字コードを書きます。
16進数の桁数はいくつでもよいので、任意の文字コードを表現できます。
したがって、?\x41は文字Aを表し、
?\x1は文字C-aを表し、
?\x8e0は
特別なエスケープの意味を持たないどんな文字のまえにもバックスラッシュを
付けることができ、しかも、無害です。
したがって、?\+は?+に等価です。
ほとんどの文字のまえにバックスラッシュを付ける理由はありません。
しかしながら、Lispコードを編集するEmacsコマンドが混乱しないように、
()\|;'`"#.,のいずれかの文字のまえにはバックスラッシュを付けるべきです。
空白、タブ、改行、ページ送りのような白文字のまえにも
バックスラッシュを付けるべきです。
しかしながら、タブなどの実際の白文字のかわりに、
\tなどの読みやすいエスケープシーケンスを使ったほうが明確です。
GNU Emacs Lispにおけるシンボル(symbol)は、 名前を持ったオブジェクトです。 シンボル名は、シンボルの表示表現としての役割があります。 普通の使い方では、名前は一意です。 つまり、2つのシンボルが同じ名前を持つことはありません。
シンボルは、変数としての役割、関数名としての役割、 あるいは、属性リストを保持する役割を果たします。 また、他のすべてのLispオブジェクトと区別するためだけの役割を 果たすこともあり、データ構造の内部にそのようなシンボルが存在することを 正確に認識できます。 ある場面においては、普通、これらのうちの1つの使い方をします。 しかし、ある1つのシンボルに対してすべての使い方をしてもかまいません。
シンボル名には、どんな文字でも含められます。
ほとんどのシンボル名は、英文字、数字、-+=*/の句読点文字で書かれます。
そのような名前では、特別な書き方は必要ありません。
名前が数に見えなければ、名前を構成する文字はなんでもよいのです。
(名前が数に見えるときには、
名前の先頭に\を書いてシンボルであると強制する。)
_~!@$%^&:<>{}の文字はあまり使われませんが、
これらにも特別な書き方は必要ありません。
これら以外の文字は、バックスラッシュでエスケープすれば、
シンボル名に含められます。
文字列におけるバックスラッシュの用法とは対照的に、
シンボル名におけるバックスラッシュは、直後の1文字をクォートするだけです。
たとえば、文字列では\tはタブ文字を表しますが、
シンボル名では英文字tをクォートするだけです。
名前にタブ文字を含むシンボルを書くには、
実際に(バックスラッシュの直後に)タブを使う必要があります。
しかし、そのようなことをするのは皆無でしょう。
Common Lispに関した注意:
Common Lispでは、小文字を明示的にエスケープしない限り、
小文字をつねに大文字に『変換』する。
Emacs Lispでは、大文字と小文字を区別する。
シンボル名の例をいくつかあげましょう。
5番目の例の+は、数として読まれるのを防ぐために
エスケープしてあることに注意してください。
6番目の例では、これは必要ありません。
なぜなら、名前の残りの部分が数としては不正だからです。
foo ;fooという名前のシンボル FOO ;FOOという名前のシンボル、fooとは別 char-to-string ;char-to-stringという名前のシンボル 1+ ;1+という名前のシンボル ; (整数の+1ではない) \+1 ;+1という名前のシンボル ; (読みにくい名前) \(*\ 1\ 2\) ;(* 1 2)という名前のシンボル(悪い名前) +-*/_~!@$%^&=:<>{} ;+-*/_~!@$%^&=:<>{}という名前のシンボル ; これらの文字をエスケープする必要はない
シーケンス(sequence)とは、 要素の順序集合を表現するLispオブジェクトです。 Emacs Lispには2種類のシーケンス、つまり、リストと配列があります。 したがって、リスト型や配列型のオブジェクトは、 シーケンス型でもあると考えられます。
配列はさらに、文字列、ベクトル、文字テーブル、ブールベクトルに細分されます。
ベクトルは任意の型の要素を保持できますが、
文字列の要素は文字である必要があり、
ブールベクトルの要素はtかnilのいずれかである必要があります。
バッファ内の文字のように、
文字列内の文字はテキスト属性を持てます(see Text Properties)。
ベクトルとブールベクトル
5
では、それらの要素が文字であったとしても、
テキスト属性を扱えません。
文字テーブルは、ベクトルに似ていますが、正しい文字コードで添字付けします。
リスト、文字列、および、その他の配列型は別のものですが、
それらには重要な類似性があります。
たとえば、それらすべてに長さlがあり、
それらのすべての要素は0からl-1で添字付けできます。
シーケンス関数と呼ばれるいくつかの関数は、
任意のシーケンス型を扱います。
たとえば、シーケンスから指定した添字の要素を取り出すには、
関数eltを使います。
See Sequences Arrays Vectors。
一般には、同一のシーケンスを二度読み取ることは不可能です。
というのは、読むたびにつねに新たにシーケンスを作成するからです。
シーケンスの入力構文を二度読むと、
同じ内容の2つのシーケンスを得ることになります。
1つ例外があります。
空リスト()は、つねに同じオブジェクトnilを表します。
コンスセル(cons cell)とは、 CARスロットおよびCDRスロットと呼ばれる 2つのポインタから成るオブジェクトです。 各スロットは、任意のLispオブジェクトを指すことができます。 また、現在CARスロットが指しているオブジェクトがなんであれ、 『コンスセルのCARは』といったいい方をします。 CDRについても同様です。
リスト(list)はコンスセルが連なったものであり、 各コンスセルのCDRスロットは、 後続のコンスセルを指すか空リストを指します。 リストに作用する関数については、See Lists。 ほとんどのコンスセルは、リストの一部分として使われるので、 リスト構造(list structure)という用語は、 コンスセルから成る任意の構造のことを意味します。
CARやCDRという名称は、Lispの歴史に由来します。
最初のLispはIBM 704で動作していました。
この計算機では、ワードを2つの部分、『番地』(address)部分、
『減数』(decrement)部分と呼ばれるものに分けていました。
CARはレジスタの番地部分の内容(Contents of Address Register)を
取り出す命令であり、
CDRはレジスタの減数部分の内容(Contents of Decrement Register)を
取り出す命令でした。
一方、『コンスセル』という名称は、
これらを作成する関数consからきています。
この関数名は、その目的、セルを作る(construction of cells)からきています。
コンスセルはLispの核心なので、 『コンスセルではないオブジェクト』に対する名称もあります。 これらのオブジェクトをアトム(atoms)と呼びます。
リストの入力構文と表示表現は同一です。 開き括弧で始まり、任意個の要素、閉じ括弧で終えます。
読み取り時には、括弧の内側の各オブジェクトが、
リストの各要素になります。
つまり、これらの要素からなるコンスセルを作ります。
コンスセルのCARスロットで要素を指します。
同じコンスセルのCDRスロットで、
リスト上のつぎの要素を保持している、
リストのつぎのコンスセルを指します。
最後のコンスセルのCDRスロットはnilを指します。
リストは、コンスセルを1対の箱で表して図示できます。
(Lispリーダがこのような図表示を読むことはない。
人間や計算機が理解できるテキスト表記と違い、
箱を用いた図表示は人間だけが理解できる。)
つぎの図は、3つの要素から成るリスト(rose violet buttercup)を表します。
--- --- --- --- --- ---
| | |--> | | |--> | | |--> nil
--- --- --- --- --- ---
| | |
| | |
--> rose --> violet --> buttercup
この図で、各箱は、任意のLispオブジェクトを指すことができるスロットを表します。 箱の対でコンスセルを表します。 各矢印は、アトムや他のコンスセルであるLispオブジェクトを指すポインタです。
この例では、最初のコンスセルのCARを表す最初の箱は、
rose(シンボル)を指しています。
あるいは、rose(シンボル)を『含んでいる』ともいいます。
最初のコンスセルのCDRを表す2番目の箱は、
つぎの1対の箱、2番目のコンスセルを指しています。
2番目のコンスセルのCARはvioletであり、
このコンスセルのCDRは3番目のコンスセルです。
3番目の(最後の)コンスセルのCDRは、nilです。
同じリスト(rose violet buttercup)を
別の方法で図表示するとつぎのようになります。
--------------- ---------------- ------------------- | car | cdr | | car | cdr | | car | cdr | | rose | o-------->| violet | o-------->| buttercup | nil | | | | | | | | | | --------------- ---------------- -------------------
内部に要素を持たないリストは、空リスト(empty list)です。
これはシンボルnilと同一です。
いいかえれば、nilはシンボルでもありリストでもあります。
Lispの構文で書き表したリストの例を示します。
(A 2 "A") ; 3要素のリスト
() ; 要素を持たないリスト(空リスト)
nil ; 要素を持たないリスト(空リスト)
("A ()") ; 文字列"A ()"だけの1要素のリスト
(A ()) ; Aと空リストから成る2要素のリスト
(A nil) ; 上と同じ
((A B C)) ; 1要素のリスト
; (その要素は3要素のリスト)
リスト(A ())や、これと同じ(A nil)を
箱と矢印で書くとつぎのようになります。
--- --- --- ---
| | |--> | | |--> nil
--- --- --- ---
| |
| |
--> A --> nil
ドット対記法(dotted pair notation)とは、
CARとCDRを明示したコンスセルを表すもう1つの構文です。
この構文では、(a . b)で、
CARがオブジェクトaであり
CDRがオブジェクトbであるコンスセルを表します。
したがって、ドット対記法は、リストの構文よりさらに汎用性があります。
ドット対記法では、リスト(1 2 3)は、
(1 . (2 . (3 . nil)))と書けます。
nilで終るリストならば、どちらの記法でも書き表せますが、
リスト記法のほうがわかりやすくて便利です。
リストを表示するときには、コンスセルのCDRがリスト以外の場合に限って
ドット対記法を使います。
ドット対記法を箱で表現してみます。
つぎの例は(rose . violet)を表したものです。
--- ---
| | |--> violet
--- ---
|
|
--> rose
最後のCDRがnil以外であるようなコンスセルの連鎖を表現するために、
リスト記法にドット対記法を組み合わせることもできます。
リストの最後の要素のあとにドットを書き、
続けて、最後のコンスセルのCDRを書きます。
たとえば、(rose violet . buttercup)は、
(rose . (violet . buttercup))に等価です。
このオブジェクトはつぎのようになります。
--- --- --- ---
| | |--> | | |--> buttercup
--- --- --- ---
| |
| |
--> rose --> violet
(rose . violet . buttercup)という構文は不正です。
これが意味することはなにもありません。
たとえあったとしても、CDRをviolet用にすでに使っているコンスセルの
CDRにbuttercupを置けということになります。
リスト(rose violet)は、(rose . (violet))に等価であり、
つぎのように図示できます。
--- --- --- ---
| | |--> | | |--> nil
--- --- --- ---
| |
| |
--> rose --> violet
同様に、3要素のリスト(rose violet buttercup)は、
(rose . (violet . (buttercup)))に等価です。
連想リスト(association list)、すなわち、alistは、 各要素がコンスセルであるように特別に構成したリストのことです。 各要素では、CARをキー(key)と考え、 CDRを連想値(associated value)と考えます。 (場合によっては、連想値を、CDRのCARに保持することもある。) 連想リストはスタックとして使われることがままあります。 というのは、リストの先頭に対応関係を追加/削除するのが簡単だからです。
たとえば、
(setq alist-of-colors
'((rose . red) (lily . white) (buttercup . yellow)))
は、変数alist-of-colorsに、3要素の連想リストを設定します。
最初の要素では、roseがキーであり、redが値です。
連想リストとそれらを操作する関数について詳しい説明は、 See Association Lists。
配列(array)は、任意のLispオブジェクトを指すための 任意個のスロットから成り、メモリの連続した場所に取ります。 配列のどの要素を参照しても、ほぼ同じ時間かかります。 一方、リストの要素を参照するときには、 リスト内の要素の位置に比例した時間が必要です。 (リストの末尾の要素を参照するには、 リストの先頭の要素を参照するより時間がかかる。)
Emacsには、4つの配列型、つまり、 文字列、ベクトル、ブールベクトル、文字テーブルがあります。
文字列は文字の配列であり、
ベクトルは任意のオブジェクトの配列です。
ブールベクトルは、tやnilだけを保持できます。
これらの種類の配列は、最大の整数値までなら、任意の長さにできます。
文字テーブルは、正しい文字コードで添字付けする疎な配列であり、
任意のオブジェクトを保持できます。
配列の最初の要素は0で添字付けする、 2番目の要素は1で添字付けする、というようになります。 これをゼロ原点(zero-origin)の添字付けと呼びます。 たとえば、4つの要素からなる配列の添字は、0、1、2、そして、3です。 最大の添字は、配列の長さより1だけ小さくなります。 いったん配列を作成すると、その長さは固定されます。
Emacs Lispのすべての配列は1次元です。 (多くの他のプログラム言語では多次元配列を扱えるが、 それは本質的ではない。 配列の配列を作れば同じ効果を得られる。) 配列のそれぞれの型に応じて、専用の入力構文があります。 詳しくは、以下を参照してください。
配列型はシーケンス型に含まれ、 配列型は、文字型、ベクトル型、ブールベクトル型、文字テーブル型を含みます。
文字列