GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/eintr/defun.html ・ emacs-doc.conao3.com

3.1 defun マクロ

Lispでは、mark-whole-bufferのようなシンボルに、関数が呼び出された際にコンピュータにどのような処理を行うかを指示するコードが紐付けられています。このコードは関数定義と呼ばれ、シンボルdefun(define functionの略)で始まるLisp式を評価することで作成されます。

以降のセクションでは、mark-whole-buffer のような Emacs のソースコードにある関数定義を取り上げていきます。本セクションでは、どのような形式になるかを確認できるよう、シンプルな関数定義について説明します。この関数定義では、例として分かりやすくするために算術演算を用いています。算術を用いた例を好まない方もいるかもしれませんが、もしそうであっても、落胆する必要はありません。この入門編の残りの部分で扱うコードの中で、算術や数学に関わるものはほとんどありません。例のほとんどは、何らかの形でテキストを扱うものです。

関数定義では、defun という語の後に最大5つの部分が続きます:

  1. 関数定義を付与すべきシンボルの名前。
  2. 関数に渡される引数のリスト。関数に引数が渡されない場合は、空のリスト () となります。
  3. 機能を説明するドキュメント。(厳密には任意ですが、強く推奨されます。)
  4. 任意で、関数をインタラクティブにするための式を指定できます。これにより、M-x に続けて関数名を入力するか、あるいは適切なキーやキーコードを入力することで関数を利用できるようになります。
  5. コンピュータに何をすべきか指示するコード:関数定義の本体。

関数定義の5つの要素が、それぞれに対応するスロットを持つテンプレート形式で構成されていると考えると分かりやすいでしょう。

(defun function-name (arguments...)
  "optional-documentation..."
  (interactive argument-passing-info)     ; optional
  body...)

例として、引数に7を掛ける関数のコードを以下に示します。(この例はインタラクティブではありません。詳細については、関数をインタラクティブにするを参照してください。)

(defun multiply-by-seven (number)
  "Multiply NUMBER by seven."
  (* 7 number))

この定義は、括弧と記号 defun で始まり、続いて関数名が記されます。

関数名の後には、関数に渡される引数を含むリストが続きます。このリストは引数リストと呼ばれます。この例では、リストにはシンボル number という1つの要素しかありません。関数が呼び出されると、このシンボルは関数の引数として使用される値に束縛されます。

引数の名前に number という言葉を選ぶ代わりに、他のどんな名前を選んでもよかったはずです。例えば、multiplicand という言葉を選ぶこともできたでしょう。私が「number」という言葉を選んだのは、このスロットにどのような値が想定されているかを示すためですが、このスロットに配置される値が関数の動作においてどのような役割を果たすかを示すために、「multiplicand」という言葉を選ぶことも同様に可能でした。foogle と呼ぶこともできましたが、それでは人間にとってそれが何を意味するのかが分からないため、不適切な選択となったでしょう。名前の選択はプログラマに委ねられており、関数の意味が明確になるように選ぶべきです。

実際、引数リスト内のシンボルには、他の関数で使用されているシンボル名であっても、任意の名前を付けることができます。引数リストで使用する名前は、その特定の定義においてプライベートなものとなります。その定義内では、その名前は関数定義の外で同じ名前が使用される場合とは異なる実体を指します。例えば、家族の中で「Shorty」というニックネームがあるとしましょう。家族が「Shorty」と呼ぶとき、それはあなたのことを指しています。しかし、家族の外、例えば映画の中では、「Shorty」という名前は別の人を指します。引数リスト内の名前はその関数定義においてプライベートであるため、関数の外で値を変更することなく、関数本体内でそのシンボルの値を変更することができます。この効果は、let 式によって得られるものと同様です。(let を参照してください。)

引数リストの後には、関数を説明するドキュメント文字列が続きます。これは、C-h f と関数名を入力した際に表示されるものです。ちなみに、このようなドキュメント文字列を記述する際は、1行目を完全な文にするようにしてください。apropos などの一部のコマンドでは、複数行にわたるドキュメント文字列の1行目しか出力されないためです。また、ドキュメント文字列がある場合は、2行目をインデントしないようにしてください。C-h f (describe-function) を使用した際に不自然に見えるためです。ドキュメント文字列は任意ですが、非常に有用であるため、作成するほぼすべての関数に含めるべきです。

例の3行目は、関数定義の本体です。(もちろん、ほとんどの関数定義はこれよりも長くなります。)この関数では、本体はリスト (* 7 number) であり、これは number の値に 7 を掛けることを指示しています。(Emacs Lisp では、+ が加算用の関数であるのと同様に、* は乗算用の関数です。)

multiply-by-seven 関数を使用すると、引数 number は実際に使用したい数値として評価されます。以下に multiply-by-seven の使用例を示しますが、まだこれを評価しようとしないでください!

(multiply-by-seven 3)

次節の関数定義で指定されている記号 number は、実際の関数呼び出し時には値 3 に束縛されます。なお、関数定義では number が括弧で囲まれていましたが、multiply-by-seven 関数に渡される引数は括弧で囲まれていません。関数定義に括弧が記述されているのは、コンピュータが引数リストの終端と関数定義の残りの部分の開始箇所を判別できるようにするためです。

この例を評価すると、おそらくエラーメッセージが表示されるでしょう。(ぜひ、試してみてください!)これは、関数の定義は記述したものの、まだコンピュータにその定義を伝えていないためです――つまり、まだEmacsに関数の定義をロードしていないということです。関数のインストールとは、Lispインタプリタに関数の定義を伝える処理のことです。インストールについては、次のセクションで説明します。