「Emacs Lisp」の版間の差分

削除された内容 追加された内容
m編集の要約なし
m編集の要約なし
4行目:
 
Emacs Lispは、ときに''Elisp''と呼ばれることもある。機能でいうと、Common Lispの影響も後にみえるが、[[Maclisp]]方言と強い関係がある
<ref>"GNU Emacs Lisp is largely inspired by Maclisp, and a little by Common Lisp. If you know Common Lisp, you will notice many similarities. However, many features of Common Lisp have been omitted or simplified in order to reduce the memory requirements of GNU Emacs. Sometimes the simplifications are so drastic that a Common Lisp user might be very confused. We will occasionally point out how GNU Emacs Lisp differs from Common Lisp." (和訳「GNU Emacs Lispは、大いにMaclispに (そして若干Common Lispに) 触発されている。もしCommon Lispをご存じなら、多数の類似点に気づくだろう。しかし、Common Lispの多くの機能は、GNU Emacsのメモリ要件のために、けずられたり、簡略化されたりしている。ときには、簡略化がすぎて、Common Lispの利用者はこんがらがるかもしれない。GNU Emacs LispとCommon Lispの違いは、ときおりふれることにする。」) Emacs Lisp Manualの"Introduction"章"History"節より</ref>。プログラミング・メソッドとして、[[プロシージャ|手続き]]指向プログラミングと[[関数型言語|関数的]]プログラミングに対応している。[[関数 (プログラミング)|関数]]をデータとして扱えるなどの強力な機能のため、([[TECO]]を拡張言語としていたオリジナルの) Emacsの書換えにあたり、[[リチャード・ストールマン]]は拡張言語としてLispを選んだ。ストールマンが[[Gosling Emacs]]をGNU Emacsへ書き換えていたとき、Common Lisp とは違ってSchemeは既に存在した。しかし、当時のワークステーションの性能は貧弱であったため、Schemeよりももっと簡単に最適化のできるLispLISP方言を開発する必要があった<ref>"So the development of that operating system, the GNU operating system, is what led me to write the GNU Emacs. In doing this, I aimed to make the absolute minimal possible Lisp implementation. The size of the programs was a tremendous concern. There were people in those days, in 1985, who had one-megabyte machines without virtual memory. They wanted to be able to use GNU Emacs. This meant I had to keep the program as small as possible." (和訳「つまり、GNU Emacsを書くことが,オペレーティング・システム、すなわち、GNUオペレーティング・システムの開発につながった。このことで、わたしは極小のLispLISP実装をつくることになった。プログラムの大きさは,重要な関心事だった。1985年当時,仮想記憶のない1メガバイトのマシンをもつ人たちは大勢いた。そんな人たちもGNU Emacsを使いたがっていた。それで私は、プログラムをなるたけ小さく作る必要があった。」) [http://www.gnu.org/gnu/rms-lisp.html "My Lisp Experiences and the Development of GNU Emacs"]より</ref>。
 
Emacs Lispは、アプリケーション・プログラミングで使われる方言群である[[Scheme]]や[[Common Lisp]]とは根本的に異なる。大きな違いの1つは、デフォルトで[[静的スコープ|字句的スコープ]]ではなく[[動的スコープ]]を使うことである。つまり、呼出し関数の局所変数は、呼び出された関数からも参照できるが、定義時のスコープで参照しているのではない。
26行目:
最初の文 <code>(defun ...)</code>は、新しい関数<code>my-split-window-function</code>を定義する。これは、<code>split-window-vertically</code> (前のウインドウ分割関数) を呼び出し、新しいウインドウが別のバッファを表示するようにする。次の文 <code>(global-set-key ...)</code> は、「<code>C-x 2</code>」というキー列に新しい関数を結び付けなおす。
 
もっと簡単に書く方法もある。Emacs Lispには、''advice''という強力な機能があり、利用者は既存の関数を再定義せずに新しいラッパーを作れるのである。adviceを使うと、上のコードは、次のように再実装できる。
 
<syntaxhighlight lang="elisp">
36行目:
これは、<code>split-window-vertically</code>が呼び出されたとき、関数の本体を実行する前に利用者の指定したコードを実行するよう命令している。
 
こういった変更は、たとえば「<code>M-x eval-buffer</code>」コマンドを使ってコードが''評価''されてはじめて効果が生ずる。Emacsの再コンパイルはおろか再起動さえいらない。Emacsのカスタム化は便利だといわれる所以である。もしEmacsの「立上げファイル」(ふつうは利用者の [[ホームディレクトリ]] にある「<code>.emacs</code>」という名前のファイル) にコードを保存すれば、次にEmacsが立ち上がったとき、Emacsはこの拡張を読み込むことになる。
 
== ソースコード ==
43行目:
メモリ空間の節約のため、Emacsの機能の多くは、必要になるまで読込まれない。追加機能一式それぞれは、「ライブラリ」というEmacsコードの集まりで実装されている。たとえば、プログラムソースコードのキーワードの強調用ライブラリや[[テトリス]]・ゲームで遊ぶライブラリなどがある。各ライブラリは、ひとつまたは複数のEmacs Lispソース・ファイルで実装される。
 
一部の関数は [[C言語]](以下、単にC)で書いてある。これは「プリミティブ」と呼ばれる(「組込み関数」とか「サブル」ともいう)。プリミティブはLispコードから呼び出すことができ、C言語のソース・ファイルを修正し再コンパイルすることでのみ変更できる。GNU Emacsでは、プリミティブを外部ライブラリにすることはできず、Emacs[[実行ファイル|実行形式]]の一部分となる。XEmacsでは、オペレーティング・システムの動的リンクのサポートを使って、プリミティブを実行時に読み込める。関数をプリミティブで書くのは、Emacs Lispからはアクセスできない外部データやライブラリを用いる必要があったり、C言語とEmacs Lispで実行速度の差が十分認められるほど頻繁に呼ばれたりする場合である。
 
ただし、C言語でのエラーはすぐに[[セグメンテーション違反]]やより些細なバグにつながるため、エディタをクラッシュさせるし、Emacs Lispの[[ガベージコレクション|ガベージ・コレクタ]]と正しく相互作用するC言語のコードを書くことはエラーを引き起こしやすいので、<!--←英語版の意味が不明瞭-->プリミティブで実装されている関数は比較的少数である。
 
=== バイトコード ===