Node:Top, Next:, Previous:(dir), Up:(dir)


Node:Copying, Next:, Previous:Top, Up:Top

GNU一般公有使用許諾書

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)本使用許諾の条項の下で ソフトウェアを複製・頒布・変更する権利をユーザに与えます。

また、各作成者や我々自身を守るために、 本フリー・ソフトウェアが無保証であることを 全ての人々が了解している必要があります。 さらに、他の誰かによって変更されたソフトウェアが頒布された場合、 受領者はそのソフトウェアがオリジナル・バージョンではないということを 知らされる必要があります。 それは、他人の関与によって原開発者に対する評価が 影響されないようにするためです。

最後に、どのフリー・プログラムもソフトウェア特許に絶えず脅かされています。 我々は、フリー・プログラムの再頒布者が個人的に特許権を取得し、 事実上そのプログラムを自分の財産にしてしまうという危険を 避けたいと願っています。 これを防ぐために我々は、いずれの特許も、 誰でも自由に使用できるように使用許諾されるべきか、 あるいは何人に対しても全く使用させないかの、 いずれかにすべきであることを明らかにしてきました。

複写・頒布・変更に対する正確な条項と条件を次に示します。

  1. 本使用許諾は、本一般公有使用許諾の各条項に従って頒布されるという 著作権者からの告知文が表示されているプログラムやその他の作成物に適用されます。 以下において「プログラム」とは、そのようなプログラムや作成物を指すものとし、 また、「プログラム生成物」とは、上述した「プログラム」自身、または、 著作権法下における全ての派生物;すなわち、その「プログラム」の全部又は一部を、 そのまま又は変更して、且つ/又は他の言語に変換して、 内部に組み込んだ作成物を意味します。 (以下、言語変換は「変更」という用語の中に無条件に含まれるものとします。) 本使用許諾によって許諾を受ける者を「あなた」と呼びます。 

    複製、頒布、変更以外の行為は本使用許諾の対象としません。 それらは本使用許諾の範囲外です。 「プログラム」を実行させる行為に関して制約はありません。 「プログラム」の出力は、 (「プログラム」を実行させて作成させたかどうかとは無関係に) その内容が「プログラム生成物」である場合に限り本使用許諾の対象となります。 これが当てはまるかどうかは、「プログラム」が何をするものかに依ります。

  2. あなたは、どのような媒体上へ複製しようとする場合であっても、 入手した「プログラム」のソース・コードを そのままの内容で複写した上で適正な著作権表示と保証の放棄を明確、 且つ適正に付記する場合に限り、複製又は頒布することができます。 その場合、本使用許諾及び無保証に関する記載部分は、 全て元のままの形で表示してください。 また、「プログラム」の頒布先に対しては、 「プログラム」と共に本使用許諾書の写しを渡してください。

    複製物の引き渡しに要する実費は請求することができます。 また、あなた独自の保証を行なう場合はそれを有償とすることができます。

  3. 次の各条件を全て満たしている限り、あなたは、 「プログラム」又はその一部分を変更して「プログラム生成物」とすることができ、 さらに、変更版や右作成物を上記第2項に従って複製又は頒布することもできます。
    1. ファイルを変更した旨とその変更日とを、変更したファイル上に明確に表示すること。
    2. 変更したか否かを問わず、凡そ「プログラム」 又はその一部分を内部に組み込んでいるか 又はそれから派生した生成物を頒布する場合には、 その全体を本使用許諾の条項に従って第三者へ無償で使用許諾すること。
    3. 変更したプログラムが実行時に通常の対話的な方法で コマンドを読むようになっているとすれば、 最も普通の方法で対話的にそのプログラムを実行する時に、 次の内容を示す文言がプリンタへ印字されるか、或いは画面に表示されること。
      • 適切な著作権表示。
      • 無保証であること(あなたが独自に保証する場合は、その旨)。
      • 頒布を受ける者も、 本使用許諾と同一の条項に従って「プログラム」を再頒布できること。
      • 頒布を受ける者が本使用許諾書の写しを参照する方法。 (例外として、「プログラム」自体は対話的であっても起動時の文言を 通常は印字しないのならば、 あなたの「プログラム生成物」はこのような文言を印字する必要はありません。)

    これらの要件は変更された作成物にも全て適用されます。 その変更版の或る部分が「プログラム」の派生物ではなく、 しかもそれ自体独立で異なる作成物だと合理的に考えられる場合、 あなたがそれらを別の作成物として頒布した時は、 本使用許諾とその条項はそれらの部分には適用されません。 しかし、それらを「プログラム生成物」の一部として頒布する場合は、 全体が本使用許諾の条項に従って頒布されなければならず、 使用許諾を受ける他の全ての者に対する許諾も プログラム全体にわたって与えられなければならず、 結果として、誰が書いたかにかかわらず、 全ての部分に本使用許諾が適用されなければなりません。

    このように、本条項の意図するところは、 完全にあなたによって書かれた作成物について、権利を要求したり、 あなたと権利関係を争うことではありません。 むしろその目的は、作成物が「プログラム生成物」 である場合にその派生物や集合物の頒布を規制することにあります。

    さらに、「プログラム」(又は「プログラム生成物」)と 「プログラム生成物」とはならない他のプログラムとを、 単に保管や頒布のために同一の媒体上にまとめて記録したとしても、 本使用許諾は他のプログラムには適用されません。

  4. あなたは、以下のうちいずれか1つを満たす限り、 上記第2項及び第3項に従って「プログラム」 (又は、上記第3項で言及している「プログラム生成物」)を オブジェクト・コード又は実行可能な形式で複製及び頒布することができます。
    1. 対応する機械読み取り可能なソース・コード一式を一緒に引き渡すこと。 その場合、そのソース・コードの引き渡しは上記第2項及び第3項に従って、 通常ソフトウェアの交換に用いられる媒体で行なわれること。
    2. 少なくとも3年間の有効期間を定め、 且つその期間内であれば対応する機械読み取り可能なソース・コード一式の複製を、 ソース頒布に関わる実費以上の対価を要求せずに提供する旨、 及びその場合には上記第2項及び第3項に従って、 通常ソフトウェアの交換に用いられる媒体で提供される旨を記載した書面を、 第三者に一緒に引き渡すこと。
    3. 対応するソース・コード頒布の申し出に際して、 あなたが得た情報を一緒に引き渡すこと。 (この選択肢は、営利を目的としない頒布であって、 且つあなたが上記の(b)項に基づいて、 オブジェクト・コード或いは実行可能形式の プログラムしか入手していない場合に限り適用される選択項目です。)

    なお、ソース・コードとは、変更作業に適した記述形式を指します。 また、実行可能形式のファイルに対応するソース・コード一式とは、 それに含まれる全モジュールに対応する全てのソース・コード、 及びあらゆる関連のインタフェース定義ファイル、 及び実行を可能にするコンパイルとインストールの制御に関する記述を指します。 特別な例外として、実行可能なファイルが動作するオペレーティング・システムの 主要な構成要素(コンパイラ、カーネルなど)と共に (ソース・コード又はバイナリのどちらかで)頒布されているものについては、 その構成要素自体が実行形式に付随していない場合に限り、 頒布されるソース・コードに含める必要はありません。

    実行可能形式またはオブジェクト・コードの頒布が、 指示された場所からの複製のためのアクセス権の賦与である場合、 同じ場所からのソース・コードの複製のための同等なアクセス権を賦与すれば、 たとえ第三者にオブジェクト・コードと共にソースの複製を強いなくとも、 ソース・コードを頒布したものとみなします。

  5. 本使用許諾が明示的に許諾している場合を除き、あなたは、 「プログラム」を複製、変更、サブライセンス、頒布することができません。 本使用許諾に従わずに「プログラム」を複製、変更、サブライセンス、 頒布しようとする行為は、それ自体が無効であり、且つ、 本使用許諾があなたに許諾している「プログラム」の権利を自動的に消滅させます。 その場合、本使用許諾に従ってあなたから複製物やその権利を得ている第三者は、 本使用許諾に完全に従っている場合に限り、 引続き有効な使用権限を持つものとします。
  6. あなたはまだ同意の印として署名していないので、 本使用許諾を受け入れる必要はありません。 しかし、あなたに「プログラム」又はその派生物を変更又は再頒布する許可を 与えるものは本使用許諾以外にはありません。 これらの行為は、あなたがもし本使用許諾を受け入れないのであれば、 法律によって禁じられます。 従って、あなたが「プログラム」(又は「プログラム生成物」)の変更又は頒布を 行えば、それ自体であなたは本使用許諾を受け入れ、且つ、 「プログラム」又はその「プログラム生成物」の複製、頒布、変更に 関するこれらの条項と条件の全てを受け入れたことを示します。
  7. あなたが「プログラム」(又はその「プログラム生成物」)を再頒布すると自動的に、 その受領者は、元の使用許諾者から、本使用許諾の条項に従って「プログラム」を 複製、頒布、変更することを内容とする使用許諾を受けたものとします。 あなたは、受領者に許諾された権利の行使について、 さらに制約を加えることはできません。 あなたには、第三者に本使用許諾の受け入れを強いる責任はありません。
  8. 裁判所の判決、又は特許侵害の申し立て、又は(特許問題に限らない) 何らかの理由の結果として、あなたに課せられた条件が本使用許諾と 相入れないものであったとしても(裁判所の命令、契約、その他によるものであれ)、 本使用許諾の条件が免除されるものではありません。 本使用許諾による責務と、その他の何らかの関連責務を同時に満たす態様で 頒布することができないならば、 あなたは「プログラム」を全く頒布してはいけません。 例えば、特許権の内容が、あなたから直接又は間接に複製を受け取った全ての人に 使用料のないプログラムの再頒布を許さないものであれば、 あなたがかかる特許上の要請と本使用許諾の両方を満足させる方法は、 「プログラム」の頒布を完全に断念することだけです。

    本条項の或る部分が何らかの特別な状況下で無効または適用不可能になった場合、 本条項のその他の残りの部分が適用されるように意図されており、また、 本条項は全体としてその他の状況に当てはまるように意図されています。

    本条項の目的は、特許やその他の財産権を侵害したり、 そのような権利に基づく主張の妥当性を争うようにあなたに 勧めることではありません。 本条項の唯一の目的は、フリー・ソフトウェアの頒布システムの完全性を守ることで、 それは公有使用許諾の実践によって履行されます。 多くの人々が、このシステムの一貫した適用を信頼して、 このシステムを通じて頒布されている幅広い範囲のソフトウェアに惜しみない貢献を してくれました。 作成者や寄贈者が他の何らかのシステムを通じてソフトウェアを 頒布したいと決めることは彼らの自由意志であり、 使用許諾を受ける者はその選択を強いることはできません。

    本条項は、本使用許諾の他の条項の意味内容が何であるかを 完全に明らかにすることを意図しています。

  9. 「プログラム」の頒布・使用が、ある国において特許又は著作権で 保護されたインタフェースのどちらかで制限される場合、 「プログラム」を本使用許諾下においた原著作権保持者は、 その国を除外する旨の明示的な頒布地域制限を加え、 それ以外の(除外されない)国に限定して頒布が 許されるようにすることができます。 そのような場合、その制限を本使用許諾の本文に あたかも書かれているかのように本使用許諾の中に組み入れられるものとします。
  10. Free Software Foundation は随時、本一般公有使用許諾の改訂版、 又は新版を公表することがあります。 そのような新しいバージョンは、 現行のバージョンと基本的に変わるところはありませんが、 新しい問題や懸案事項に対応するために細部では異なるかもしれません。

    各バージョンは、バージョン番号によって区別します。 「プログラム」中に本使用許諾のバージョン番号の指定がある場合は、 その指定されたバージョンか、又はその後にFree Software Foundationから 公表されているいずれかのバージョンから1つを選択して、 その条項と条件に従ってください。 「プログラム」中に本使用許諾のバージョン番号の指定がない場合は、 Free Software Foundation が公表したどのバージョンでも選択することができます。

  11. 「プログラム」の一部を頒布条件の異なる他のフリー・プログラムに 組み込みたい場合は、その開発者に書面で許可を求めてください。 Free Software Foundation が著作権を持っているソフトウェアについては、 Free Software Foundation へ書面を提出してください。 このような場合に対応するために我々は例外的処理をすることもありますが、 その判断基準となるのは、次の2つの目標の実現に合致するか否かという点です。 即ち、1つは我々のフリー・ソフトウェアの全ての派生物を フリーな状態に保つことであり、もう1つはソフトウェアの共有と再利用とを 広く促進させることです。
  12. 「プログラム」は無償で使用許諾されますので、適用法令の範囲内で、 「プログラム」の保証は一切ありません。 著作権者やその他の第三者は全く無保証で「そのまま」の状態で、且つ、 明示か暗黙であるかを問わず一切の保証をつけないで提供するものとします。 ここでいう保証とは、市場性や特定目的適合性についての暗黙の保証も含まれますが、 それに限定されるものではありません。 「プログラム」の品質や性能に関する全てのリスクはあなたが負うものとします。 「プログラム」に欠陥があるとわかった場合、 それに伴う一切の派生費用や修理・訂正に要する費用は全てあなたの負担とします。
  13. 適用法令の定め、又は書面による合意がある場合を除き、 著作権者や上記許諾を受けて「プログラム」の変更・再頒布を為し得る第三者は、 「プログラム」を使用したこと、 または使用できないことに起因する一切の損害について何らの責任も負いません。 著作権者や前記の第三者が、そのような損害の発生する可能性について 知らされていた場合でも同様です。 なお、ここでいう損害には通常損害、特別損害、偶発損害、間接損害が含まれます (データの消失、又はその正確さの喪失、あなたや第三者が被った損失、 他のプログラムとのインタフェースの不適合化、等も含まれますが、 これに限定されるものではありません)。

注意

英文文書(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 wshow cは各々、 本一般公有使用許諾の関連する部分を表示するコマンドを指します。 もちろん、あなたが使うこれらのコマンドはshow wshow cといった 呼び名でなくても構いません。 さらに、それらのコマンドはあなたのプログラムに合わせる為に、 マウスでクリックしたりメニュー形式にすることもできます。

また、必要と認めた場合には、あなたの雇い主 (あなたがプログラマとして働いている場合)や在籍する学校から、 そのプログラムに対する「著作権放棄」を認めた署名入りの書面を入手してください。 ここにその文例を載せます。名前は変えてください。

Yoyodyne, Inc. は、James Hacker が開発したプログラム`Gnomovision'
(コンパイラにつなげるプログラム)についての著作権法上の全ての権利を放棄する。

Ty Coon の署名, 1 April 1989
Ty Coon, 副社長

本一般公有使用許諾は、あなたのプログラムを財産権の対象となっている 他のプログラムに組み込むことは認めていません。 あなたのプログラムがサブルーチン・ライブラリであって、 あなたがそのライブラリを財産権の対象となっている他のアプリケーションと リンクさせることによって、さらに有用なものにしようとする場合には、 本使用許諾書の代わりに、GNUライブラリ一般公有使用許諾書に従ってください。


Node:Introduction, Next:, Previous:Copying, Up:Top

はじめに

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版です。


Node:Caveats, Next:, Up:Introduction

警告

本書は、数多くの草稿を重ねてきました。 ほぼ完璧に近いはずですが、誤りは皆無ではありません。 ふれていない話題も少なからずあります。 (大部分の個別のモードのような)副次的と捉えている話題や、 まだ執筆していない話題もあります。 完全にはこれらに対処しきれませんので、 意図的に省いたことがらもあります。 たとえば、VMSにおける利用方法に関する情報です。

本書で取り上げたことがらに関しては、本書は完璧であるべきですから、 例題や記述内容から章や節の構成順序といったことまで、 広く意見を求めています。 混乱を招くような記述や、本書でふれていないことがらを 学ぶためにソースや実験で調べる必要があるときには、 本書を改訂すべきなのでしょう。 そのときは、ぜひ、教えてください。

意見や訂正は、下記へメイルしてください。

bug-lisp-manual@gnu.org

ここに蓄積されたメイルは、誰かが改訂作業を始めるまでは、読み出しません。 改訂までに、数か月、ときには、数年経過することもあります。 ですから、返事がないと憤慨しないでください。 あなたのメイルは、そのうち処理されます。 Emacs保守グループに迅速に連絡したい場合には、 bug-gnu-emacs@gnu.orgにメイルしてください。


Node:Lisp History, Next:, Previous:Caveats, Up:Introduction

Lispの歴史

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を使います。


Node:Conventions, Next:, Previous:Lisp History, Up:Introduction

表記法

本節では、本書で用いる表記法を説明します。 本節を読み飛ばして、あとで参照してもかまいません。


Node:Some Terms, Next:, Up:Conventions

用語

本書では、『Lispリーダ』および『Lispプリンタ』という言葉で、 Lispオブジェクトのテキスト表現を実際のLispオブジェクトに変換する Lisp内部のルーティン群、および、逆の変換を行うルーティン群を指します。 詳しくは、See Printed Representation。 本書の読者を『プログラマ』と考えて『読者』と呼びます。 『ユーザー』とは作者自身を含めたLispプログラムを使う人のことです。

Lispコードの例は、(list 1 2 3)という形式で、 このフォントで記します。 メタな変数の名前や説明対象の関数に対する引数の名前は、 first-numberという形式で、このフォントで書きます。


Node:nil and t, Next:, Previous:Some Terms, Up:Conventions

nilt

Lispでは、シンボル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では、niltは特別なシンボルであり、 評価するとそれ自身になります。 そのため、これらをプログラム内で定数として使うとき、 これらをクォートする必要はありません。 これらの値を変更しようとすると、エラーsetting-constantになります。 コロン(:)で始まる名前のシンボルも同様です。 See Constant Variables


Node:Evaluation Notation, Next:, Previous:nil and t, Up:Conventions

評価の表記法

評価可能な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)


Node:Printing Notation, Next:, Previous:Evaluation Notation, Up:Conventions

結果表示の表記法

本書の数多くの例題は、評価するとテキストを表示します。 (*scratch*バッファのような)Lisp対話バッファで例題のコードを 実行すると、表示テキストはバッファに挿入されます。 (関数eval-regionで評価するなどの) 別の手段で例題を実行すると、表示テキストはエコー領域に表示されます。 エコー領域に表示されるテキストは、1行に切り詰められていることに 注意してください。

本書の例題では、表示場所には無関係に、 表示テキストを-|で表します。 フォームを評価した結果返される値(ここではbar)は、 後続の行に分けて書きます。

(progn (print 'foo) (print 'bar))
     -| foo
     -| bar
     => bar


Node:Error Messages, Next:, Previous:Printing Notation, Up:Conventions

エラーメッセージ

エラーを通知する例題もあります。 これは、通常、エコー領域にエラーメッセージを表示します。 エラーメッセージは、error-->で始まる行に示します。 エコー領域には、error-->は表示されないことに注意してください。

(+ 23 'x)
error--> Wrong type argument: number-or-marker-p, x


Node:Buffer Text Notation, Next:, Previous:Error Messages, Up:Conventions

バッファ内のテキストの表記法

バッファ内のテキストを修正する例題もあります。 このような場合、『実行前』と『実行後』のテキストを示します。 それらの例題では、バッファ名を含めたダッシュから成る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 ----------


Node:Format of Descriptions, Previous:Buffer Text Notation, Up:Conventions

記述形式

関数、変数、マクロ、コマンド、ユーザーオプション、 スペシャルフォームは、本書では統一した形式で記述します。 第1行目は、それぞれの名前と、引数があれば引数群です。 これに説明文が続き、場合によっては例題も示します。


Node:A Sample Function Description, Next:, Up:Format of Descriptions

関数の記述例

関数の記述では、まず始めに説明対象の関数名があります。 同じ行には、引数名の並びも続きます。 これらの名前は、説明文の中で引数の値を参照するために使います。

引数ならびにキーワード&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...)

integerinteger1bufferなどの)型名を名前とする引数は、 その型の値であると仮定します。 (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だけ)増やす。 vartoに等しくなると、 bodyを実行せずにループから抜ける。 例を示す。
(count-loop (i 0 10)
  (prin1 i) (princ " ")
  (prin1 (aref vector i))
  (terpri))

fromtoを省略すると、 ループ開始前にvarnilを束縛し、 各反復の開始時にvarnil以外であるとループから抜け出る。

(count-loop (done)
  (if (pending)
      (fixit)
    (setq done t)))

このスペシャルフォームでは、引数fromtoは省略できるが、 両者を同時に指定するか、同時に省略すること。 これらを指定した場合、incを指定してもよい。 これらの引数は、引数varとともにリストにまとめる。 これはbodyと区別するためであり、 bodyは残りのフォームの要素すべてを含む。


Node:A Sample Variable Description, Previous:A Sample Function Description, Up:Format of Descriptions

変数の記述例

変数(variable)は、値を保持するための名前です。 ユーザーはどんな変数でも設定できますが、 ユーザーが変更可能な特定の変数群があり、 それらをユーザーオプション(user options)と呼びます。 普通の変数もユーザーオプションも関数の記述と同じ形式で示しますが、 それらに引数はありません。

仮想的な変数electric-future-mapの記述例を示します。

electric-future-map Variable
この変数の値は、Electric Command Futureモードで使用する 完全なキーマップである。 このマップに含まれる関数は、まだ実行していないコマンドの編集を可能にする。

ユーザーオプションの記述も同じ形式ですが、 「変数」のかわりに「ユーザーオプション」です。


Node:Version Info, Next:, Previous:Conventions, Up:Introduction

版情報

これらの機構は、使用中の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。


Node:Acknowledgements, Previous:Version Info, Up:Introduction

謝辞

本書は、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。


Node:Lisp Data Types, Next:, Previous:Introduction, Up:Top

Lispのデータ型

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の各標準型の表示表現と入力構文を説明します。 これらの型の使用方法の詳細は、あとの章に譲ります。


Node:Printed Representation, Next:, Up:Lisp Data Types

表示表現と入力構文

オブジェクトの表示表現(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


Node:Comments, Next:, Previous:Printed Representation, Up:Lisp Data Types

コメント

コメント(comment)は、プログラム内に書かれたテキストであり、 プログラムを読む人間のためだけにあり、 プログラムの意味にはまったく影響しません。 Lispでは、文字列や文字定数の外にあるセミコロン(;)で コメントを始めます。 コメントは行末までです。 Lispリーダは、コメントを破棄します。 コメントは、 Lispシステム内部でプログラムを表すLispオブジェクトの一部にはなりません。

#@countという書き方は、 後続のcount個の文字を飛び越します。 これは、プログラムで生成したバイナリデータを含むコメントに便利です。 Emacs Lispのバイトコンパイラは、出力ファイルにこのようなコメントを使います (see Byte Compilation)。 しかしながら、ソースファイル向きではありません。

コメントの体裁に関する慣習については、See Comment Tips


Node:Programming Types, Next:, Previous:Comments, Up:Lisp Data Types

プログラミング向けの型

Emacs Lispには、大きく2種類の型があります。 Lispのプログラミングに関わるものと、編集に関わるものです。 前者は、さまざまな形でLispの多くの実装に見られます。 後者は、Emacs Lispに固有です。


Node:Integer Type, Next:, Up:Programming Types

整数型

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


Node:Floating Point Type, Next:, Previous:Integer Type, Up:Programming Types

浮動小数点数

Emacsは浮動小数点数を扱えます (ただし、コンパイル時のオプションで使用不可にできる)。 浮動小数点数の範囲は、計算機に依存します。

浮動小数点数の表示表現には、 小数点(に続けて1桁以上の小数部分)または指数、 あるいは、その両方が必要です。 たとえば、1500.015e215.0e21.5e3.15e4は、同じ1500という値の 浮動小数点数を書く5つの方法です。 どれも、まったく等価です。

詳しくは、See Numbers


Node:Character Type, Next:, Previous:Floating Point Type, Up:Programming Types

文字型

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-AM-Aです。 \M-と一緒に8進文字コードも使えますし(下記参照)、 \C-や文字向けの他の構文も使えます。 したがって、M-A?\M-Aと書いたり?\M-\101と書けます。 同様に、C-M-b?\M-\C-b?\C-\M-b?\M-\002と書けます。

図形文字の大文字小文字は、その文字コードで示されます。 たとえば、ASCIIではaAの文字を区別します。 しかし、ASCIIではコントロール文字の大文字小文字を表現できません。 Emacsでは、コントロール文字を打つときに使ったシフトキーを表すために のビットを付加します。 このような区別はX端末や他の特別な端末を使っている場合に限り可能です。 普通の端末ではこのような区別を計算機に送れません。

Xウィンドウシステムでは、 文字に設定可能な修飾ビットが他に3つあります。 ハイパー(hyper)、スーパー(super)、アルト(alt)です。 これらの修飾ビットの構文は、 \H-\s-\A-です。 (これらのプレフィックスでは、大文字小文字を区別する。) したがって、?\H-\M-\A-xAlt-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などの読みやすいエスケープシーケンスを使ったほうが明確です。


Node:Symbol Type, Next:, Previous:Character Type, Up:Programming Types

シンボル型

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)という名前のシンボル(悪い名前)
+-*/_~!@$%^&=:<>{}  ; +-*/_~!@$%^&=:<>{}という名前のシンボル
                    ;   これらの文字をエスケープする必要はない


Node:Sequence Type, Next:, Previous:Symbol Type, Up:Programming Types

シーケンス型

シーケンス(sequence)とは、 要素の順序集合を表現するLispオブジェクトです。 Emacs Lispには2種類のシーケンス、つまり、リストと配列があります。 したがって、リスト型や配列型のオブジェクトは、 シーケンス型でもあると考えられます。

配列はさらに、文字列、ベクトル、文字テーブル、ブールベクトルに細分されます。 ベクトルは任意の型の要素を保持できますが、 文字列の要素は文字である必要があり、 ブールベクトルの要素はtnilのいずれかである必要があります。 バッファ内の文字のように、 文字列内の文字はテキスト属性を持てます(see Text Properties)。 ベクトルとブールベクトル 5 では、それらの要素が文字であったとしても、 テキスト属性を扱えません。 文字テーブルは、ベクトルに似ていますが、正しい文字コードで添字付けします。

リスト、文字列、および、その他の配列型は別のものですが、 それらには重要な類似性があります。 たとえば、それらすべてに長さlがあり、 それらのすべての要素は0からl-1で添字付けできます。 シーケンス関数と呼ばれるいくつかの関数は、 任意のシーケンス型を扱います。 たとえば、シーケンスから指定した添字の要素を取り出すには、 関数eltを使います。 See Sequences Arrays Vectors

一般には、同一のシーケンスを二度読み取ることは不可能です。 というのは、読むたびにつねに新たにシーケンスを作成するからです。 シーケンスの入力構文を二度読むと、 同じ内容の2つのシーケンスを得ることになります。 1つ例外があります。 空リスト()は、つねに同じオブジェクトnilを表します。


Node:Cons Cell Type, Next:, Previous:Sequence Type, Up:Programming Types

コンスセルとリスト型

コンスセル(cons cell)とは、 CARスロットおよびCDRスロットと呼ばれる 2つのポインタから成るオブジェクトです。 各スロットは、任意のLispオブジェクトを指すことができます。 また、現在CARスロットが指しているオブジェクトがなんであれ、 『コンスセルのCARは』といったいい方をします。 CDRについても同様です。

リスト(list)はコンスセルが連なったものであり、 各コンスセルのCDRスロットは、 後続のコンスセルを指すか空リストを指します。 リストに作用する関数については、See Lists。 ほとんどのコンスセルは、リストの一部分として使われるので、 リスト構造(list structure)という用語は、 コンスセルから成る任意の構造のことを意味します。

CARCDRという名称は、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番目のコンスセルのCARvioletであり、 このコンスセルの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


Node:Dotted Pair Notation, Next:, Up:Cons Cell Type

ドット対記法

ドット対記法(dotted pair notation)とは、 CARCDRを明示したコンスセルを表すもう1つの構文です。 この構文では、(a . b)で、 CARがオブジェクトaであり CDRがオブジェクトbであるコンスセルを表します。 したがって、ドット対記法は、リストの構文よりさらに汎用性があります。 ドット対記法では、リスト(1 2 3)は、 (1 . (2 . (3 . nil)))と書けます。 nilで終るリストならば、どちらの記法でも書き表せますが、 リスト記法のほうがわかりやすくて便利です。 リストを表示するときには、コンスセルのCDRがリスト以外の場合に限って ドット対記法を使います。

ドット対記法を箱で表現してみます。 つぎの例は(rose . violet)を表したものです。

    --- ---
   |   |   |--> violet
    --- ---
     |
     |
      --> rose

最後のCDRnil以外であるようなコンスセルの連鎖を表現するために、 リスト記法にドット対記法を組み合わせることもできます。 リストの最後の要素のあとにドットを書き、 続けて、最後のコンスセルのCDRを書きます。 たとえば、(rose violet . buttercup)は、 (rose . (violet . buttercup))に等価です。 このオブジェクトはつぎのようになります。

    --- ---      --- ---
   |   |   |--> |   |   |--> buttercup
    --- ---      --- ---
     |            |
     |            |
      --> rose     --> violet

(rose . violet . buttercup)という構文は不正です。 これが意味することはなにもありません。 たとえあったとしても、CDRviolet用にすでに使っているコンスセルの CDRbuttercupを置けということになります。

リスト(rose violet)は、(rose . (violet))に等価であり、 つぎのように図示できます。

    --- ---      --- ---
   |   |   |--> |   |   |--> nil
    --- ---      --- ---
     |            |
     |            |
      --> rose     --> violet

同様に、3要素のリスト(rose violet buttercup)は、 (rose . (violet . (buttercup)))に等価です。


Node:Association List Type, Previous:Dotted Pair Notation, Up:Cons Cell Type

連想リスト型

連想リスト(association list)、すなわち、alistは、 各要素がコンスセルであるように特別に構成したリストのことです。 各要素では、CARキー(key)と考え、 CDR連想値(associated value)と考えます。 (場合によっては、連想値を、CDRCARに保持することもある。) 連想リストはスタックとして使われることがままあります。 というのは、リストの先頭に対応関係を追加/削除するのが簡単だからです。

たとえば、

(setq alist-of-colors
      '((rose . red) (lily . white)  (buttercup . yellow)))

は、変数alist-of-colorsに、3要素の連想リストを設定します。 最初の要素では、roseがキーであり、redが値です。

連想リストとそれらを操作する関数について詳しい説明は、 See Association Lists


Node:Array Type, Next:, Previous:Cons Cell Type, Up:Programming Types

配列型

配列(array)は、任意のLispオブジェクトを指すための 任意個のスロットから成り、メモリの連続した場所に取ります。 配列のどの要素を参照しても、ほぼ同じ時間かかります。 一方、リストの要素を参照するときには、 リスト内の要素の位置に比例した時間が必要です。 (リストの末尾の要素を参照するには、 リストの先頭の要素を参照するより時間がかかる。)

Emacsには、4つの配列型、つまり、 文字列、ベクトル、ブールベクトル、文字テーブルがあります。

文字列は文字の配列であり、 ベクトルは任意のオブジェクトの配列です。 ブールベクトルは、tnilだけを保持できます。 これらの種類の配列は、最大の整数値までなら、任意の長さにできます。 文字テーブルは、正しい文字コードで添字付けする疎な配列であり、 任意のオブジェクトを保持できます。

配列の最初の要素は0で添字付けする、 2番目の要素は1で添字付けする、というようになります。 これをゼロ原点(zero-origin)の添字付けと呼びます。 たとえば、4つの要素からなる配列の添字は、0、1、2、そして、3です。 最大の添字は、配列の長さより1だけ小さくなります。 いったん配列を作成すると、その長さは固定されます。

Emacs Lispのすべての配列は1次元です。 (多くの他のプログラム言語では多次元配列を扱えるが、 それは本質的ではない。 配列の配列を作れば同じ効果を得られる。) 配列のそれぞれの型に応じて、専用の入力構文があります。 詳しくは、以下を参照してください。

配列型はシーケンス型に含まれ、 配列型は、文字型、ベクトル型、ブールベクトル型、文字テーブル型を含みます。


Node:String Type, Next:, Previous:Array Type, Up:Programming Types

文字列型

文字列