Next: , Previous: , Up: Writing Defuns   [Contents][Index]


3.1 The defun Macro

Lispにおいてmark-whole-bufferのようなシンボルには、関数が呼び出された際にコンピューターが行うべきことを示すコードが付加されています。これは関数定義(function definition)と呼ばれるコードであり、シンボルdefun (define function(関数を定義する)の省略形)で始まるLisp式を評価することによって作成されます。

以降のセクションにおいて、わたしたちはmark-whole-bufferのようなEmacsのソースコードに由来する関数定義を目にすることになります。このセクションでは関数定義の見栄えを確認できるように、シンプルな関数定義について説明するつもりです。この関数定義をシンプルな例とするために算術演算を使用しています。算術演算を使用した例を好まない人もいます。もしあなたがそのような人であっても心配は無用です。この入門書で学んでいく残りの部分のコードには、算術や数学はほとんど含まれていません。ほとんどの例には何らかの形でテキストが含まれています。

関数定義は単語defunの後に続く最大で5つの部分によって構成されます:

  1. 関数定義を付加するシンボルの名前。
  2. 関数に渡される引数のリスト。関数に渡す引数がなければ空のリスト()
  3. 関数を説明するドキュメント(技術的にはオプションだが強く推奨)。
  4. オプションとして、M-xとタイプしてから関数名を入力したり、適正なキーやキーコードをタイプすることで使用できるように、関数をインタラクティブ(interactive)にする式。
  5. コンピューターが何をすべきか指示するコード。その関数定義のbody(本体)

関数定義とは、関数定義を構成する5つの部分それぞれにたいしてスロットを備えたテンプレートとして組織化されていると考えれば理解の助けになるかもしれません。

(defun function-name (arguments…)
  "optional-documentation…"
  (interactive argument-passing-info)     ; オプション
  body…)

例として、以下は引数に7を乗ずる関数のコードです(これはinteractiveな例ではありません; interactiveについてはMaking a Function Interactiveを参照してください)。

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

この定義はカッコとシンボルdefunで始まり、その後に関数の名前が続きます。

関数の名前の後に、この関数に渡されることになる引数を含んだリストが続きます。このリストは引数リスト(argument list)と呼ばれるものです。この例において、リストにはnumberという1つの要素しか含まれていません。この関数が使用される際には、この関数の引数に使用された値がこのシンボルにバインドされます。

引数名として単語numberではない、他の任意の名前を選ぶことができます。たとえば単語multiplicandを選んでもよいでしょう。わたしはこのスロット向けにどんな値の種類が期待されているかを告げるために“number(数値)”という単語を選びました。でも同様にこのスロットに置かれる値が関数の動作において果たす役割りを示すために、単語“multiplicand(被乗数)”を選ぶこともできたのです。この引数をfoogleと呼ぶこともできましたが、これは人には何の意味か判らないでしょうから悪い選択です(訳注: Googleを使わずネットでわざわざ人に尋ねることをfoogleと言うようです)。引数の名前はプログラマーに委ねられており、その関数の意味が明解になるよう選択するべきです。

実際のところ、引数リスト内のシンボルにたいして任意の名前を選択できます。そのシンボル名が他の関数で使用されていたとしても、あなたが引数リスト内で使用する名前は個々の定義にたいしてプライベートです。ある定義においてその名前が参照するエンティティは、その関数定義の外側で同じ名前を使用したエンティティの参照とは異なるのです。家庭においてあなたが“Shorty”というニックネームをもつとします。あなたの家族が“Shorty”と呼ぶ際には、あなたのことを意味しています。しかし家庭の外、たとえば映画でなら“Shorty”という名前が参照するのは他の誰かです。引数リストの名前はその関数定義にたいしてプライベートなので、そのようなシンボルの値については関数外部の同じシンボルの値を変更することなく、関数の本体内部で変更することができます。これはlet式が生み出す効果と似ています(letを参照)。

引数リストの後には、その関数を説明するドキュメント文字列(documentation string)が続きます。これはあなたがC-h fの後に関数の名前をタイプしたときに目にするであろう文字列です。ついでながら、もしあなたがこのようなドキュメント文字列を記述する際には、最初の行を完結したセンテンスにする必要があります。なぜならaproposのようないくつかのコマンドは、複数行からなるドキュメント文字列の最初の行だけをプリントするからです。更にドキュメント文字列の2行目をインデントするべきではありません。2行目をインデントしてしまうと、C-h f (describe-function)を使用した際におかしな見栄えになってしまうからです。ドキュメント文字列はオプションですがとても役に立つので、あなたが記述するほとんどすべての関数に含めるべきです。

この例の3行目は関数定義のbodyから構成されています(もちろんこれより長い定義をもつ関数がほとんどです)。この関数のbodyはリスト(* 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インタープリターにたいしてその定義が関数であることを伝えるプロセスが関数のインストールです。インストールについては次のセクションで説明します。

This page has generated for branch:work/add_lispintr, commit:65845cf60c073f2f3182d1d07483530e9bbe1d96 to check Japanese translation.