Next: , Previous: , Up: Functions   [Contents][Index]


12.4 Defining Functions

わたしたちは通常、関数を最初に作成したときに名前を与えます。これは関数の定義(defining a function)と呼ばれ、defunマクロにより行われます。

Macro: defun name args [doc] [declare] [interactive] body…

defunは新たなLisp関数を定義する通常の方法です。これは、引数リストargs、およびbodyにより与えられるbodyフォームとともに、シンボルnameを関数として定義します。nameargsを、クォートする必要はありません。

docが与えられた場合、それはその関数のドキュメント文字列を指定する文字列であるべきです(Function Documentationを参照してください)。declareが与えられた場合、それは関数のメタデータを指定する、declareフォームであるべきです(Declare Formを参照してください)。interactiveが与えられた場合、それは関数が対話的に呼び出される方法を指定するinteractiveフォームであるべきです(Interactive Callを参照してください)。

defunのreturn値は定義されていません。

以下にいくつか例を示します:

(defun foo () 5)
(foo)
     ⇒ 5

(defun bar (a &optional b &rest c)
    (list a b c))
(bar 1 2 3 4 5)
     ⇒ (1 2 (3 4 5))
(bar 1)
     ⇒ (1 nil nil)
(bar)
error→ Wrong number of arguments.

(defun capitalize-backwards ()
  "Upcase the last letter of the word at point."
  (interactive)
  (backward-word 1)
  (forward-word 1)
  (backward-char 1)
  (capitalize-word 1))

意図せず既存の関数を再定義しないように、注意してください。defuncarのようなプリミティブ関数でさえ、躊躇なく問い合わせもなしに再定義します。Emacsががががこれを妨げることはありません。なぜなら関数の再定義は故意に行われることがあり、そのような意図した再定義を、意図しない再定義と見分ける方法はないからです。

Function: defalias name definition &optional doc

この関数は、定義definition(任意の有効なLisp関数)とともに、シンボルnameを関数として定義します。この関数のreturn値は未定義です。

docが非nilの場合、それは関数nameのドキュメントになります。それ以外は、definitionにより提供されるドキュメントが使用されます。

内部的には、defaliasは通常、定義のセットにfsetを使用します。しかしnamedefalias-fset-functionプロパティーをもつ場合、fsetを呼び出すかわりに、それに割り当てられた値が使用されます。

defaliasを使う正しい場所は、特定の関数名がまさに定義される場所 — 特にソースファイルがロードされるとき明示的にその名前が出現する場所です。これはdefaliasが、defunと同じように、どれが関数を定義するファイルなのか記録するからです(Unloadingを参照してください)。

それとは対象的に、他の目的のために関数を操作するプログラムでは、そのような記録を保持しないfsetを使用するほうがよいでしょう。Function Cellsを参照してください。

defundefaliasで新たなプリミティブ関数を作成することはできませんが、任意の関数定義を変更するのに使用することができ、通常の定義がプリミティブであるcarx-popup-menuのような関数でさえ変更することができます。しかし、これは危険なことです。たとえば、Lispの完全性を損なうことなく、carを再定義するのはほとんど不可能だからです。それほど有名ではないx-popup-menuのような関数の再定義では、危険は減るものの、それでも期待したとおりに機能しないかもしれません。Cコードにこのプリミティブの呼び出しがある場合、それは直接そのプリミティブのC定義を呼び出すので、シンボル定義を変更しても、それらに影響はありません。

defsubstも参照してください。これはdefunのように関数を定義して、それのインライン展開を処理するようLispコンパイラーに指示します。Inline Functionsを参照してください。