詳細な部分や例外的な部分を無視して考えると、 Lisp におけるシンボルは何か名前を 持つものです。 (通常)シンボルは文字、数字、その他の文字 (大抵は、 -*&^%$@!~_+=\)からなる名前を持ちます。以下に示した各行は(それぞれ) 1 つのシン ボル名を示します。
foo1 foobar foo-bar foo+=_.bar!!! FOO lose,win
(大文字は小文字とは異なります。このため foo と FOO は異なるシンボルになります)
スペース(やタブやニューライン)、() とクォートマークは Lisp の区切り文字に含ま れます。これらはシンボル名には含まれません。
シンボルの名前は、しばしばあたかもそれがシンボルであるかのように語られます。 (しかし)実際には、私が 3つの文字からなる `bil' ではないように、シンボルもその 名前ではありません。私達は私について "Bil" であると語ります、そして foo という 名前のシンボルについてはあたかもそれが foo であるかのように語ります。多くの場 合、この区別は無視されます。
シンボルは、それに対する値を持つことができます。これを示すため、*scratch* バッ ファに
fill-column
をタイプし、ラインフィード (通常は LF もしくは LFD と示されたキー) でターミ ネートして下さい。ラインフィードキーを持たない端末では、 C-j とタイプします。 これはコンピュータに(ラインフイードと)同じ文字を送ります。
こうすると、Lisp はこのシンボルに対する値を print します。 (通常) fill-column は、値 70 を持ちます (fill-column は fill コマンドにおける 1行当りの最大許容長 (訳注:maximum allowable length)として用いられます)。
Lisp は、正しく定義されたまとまりが入力されることを望みます。ここでは、この チャンクのことを式を呼びます。 *scratch* バッファで LFD をタイプすると、 Lisp はその前にある式を逆方向に見、その値を print します (C-h k LFD とタイプし FLD のキーバインディングを調べて見て下さい)。今の所、私達は式の種類としてシンボル しか知らないわけですが、まもなくもっと多くのものを知ることになります。
以後、(各々の)式の例の後に、`>' で始まる行を置きます。この行は (その例におけ る) その直前の式の結果の値を示します。
以下、さらにいくつかのシンボルとその値の例を示します。
c-indent-lebel => 2 ;C コードにおいて、新しいブロックごとにどれだけインデントするか tab-width => 8 ;通常のTAB 幅 left-margin => 0 ;レフトマージンの位置
値のためにシンボルを用いる場合、そのシンボルは変数と呼ばれます。変数の値は固定 されていません。そのため、それを "variables(訳注:変化しうるもの/変数) と呼ぶ わけです。 c-indent-lebel, tab-width, left-margin は(全て)変数であり、 (訳注: その値を)変更することができます。
tab-width の値を変えるには、(以下に示すように) Lisp の setq を用います。
(setq tab-width 20) => 20
(もちろん、LFD でターミネートします)
(setq tab-width 20) は式で、値 20 を持ちます。また、tab-width の値を変える効果 を持ちます。
この後、バッファにタブを入れると、20 カラムの幅を移動すことになります。試して みて下さい! (Lisp インタラクションモードでは、TAB キーは Lisp コードを正しく インデントするよう再定義されています。実際にタブ文字を入れるためには、C-q TAB をタイプしなくてはいけません)
これまでに、シンボルやコンスタントが式であることを見てきましたが、(setq tab- width 20) は式の取りうる、別の形式(括弧の対で囲まれたシンボルやコンスタント) を示しています。
新しく (例えば、foo という名前の)シンボルを作り、このシンボルの値を設定しま しょう。
(setq foo 2) => 2
さて、ここで(Lisp に) foo の値を示すよう指示すると:
foo => 2
前のコマンドに従い、値は 2 になります。
変数の値を変えてその値を見るというのはそれほど面白くもありません。私達は、これ らの値で何かしたいわけです。 (Lisp では) 関数が、これらの値を用いてあることを 行ないます。ある関数に仕事をさせるためには、その関数の名前を ( の後に置いた形 の括弧で囲んだ式を書きます。
(変数として用いられていてもそれは値ではないというのと同様に、シンボルは関数を (名前で)指すのに用いられますが、それ自体が関数であるわけではありません。この違 いは、この違いが重要でない場合しばしば無視されます)
算術における基本関数のように良く知られている Lisp 関数がいくつか存在していま す。
(+ 5 5) => 10 (- 10 2) => 8 (* 5 foo) => 10 (/ 10 foo) => 5
関数がそれに対して操作を行なう変数は、アーギュメントと呼ばれます。上の例では、 5 と 5 は関数 + に対するアーギュメントで、 10 と 2 は関数 - に対するアーギュメ ントです。 3 番目の例において 5 と foo の値は * に対するアーギュメントです。
(掛け算の関数) * に対するアーギュメント foo を書く際、実際のアーギュメントは変 数 foo の値である点に注意して下さい。これは変数 foo の値を変更すると異なる値が 得られることを意味します。
(setq foo 100) => 10 foo => 10 (* 5 foo) => 50
Lisp がシンボルの値を見い出すことを、(Lisp が) そのシンボルを評価すると言いま す。 Lisp が式の値を作り出す(訳注:figures out)ことを、(Lisp が) その式を評価 すると言います。式は(全て) 評価されると、(エラーにならない限り)ある値になりま す。式の評価である値を得ると、"その式はその値を返した" と言うか "その関数はそ の値を返した" と言います。
このように、正しい Lisp を話すためには "Lisp は式 (+ 5 5) を評価し、値 10 を 返した" もしくは、"アーギュメント 5 と 5 を与えると、関数 + は値 10 を返す" と 言わなくてはいけません。
複雑な Lisp の式は、よりシンプルな式から作られてます。例へば、(* 5 foo) という 複雑な式に対し、Lisp はそれを評価し、値 50 を返します。このため、Lisp はまず * に対する各々のアーギュメントを評価します。 (各アーギュメントは式で) Lisp は 5 を評価し 5 を得、 foo を評価し 10 を得、関数 * が 5 掛る 10 を行ない 50 を得ま す。
"Lisp が(関数に対する)アーギュメントを評価するということは、 (それが適切な値に 評価されるものであれば) どんな種類の式でもアーギュメントとして用いることができ るということを意味する" というのは正しいでしょうか? もちろん!
複雑な式を、(別の)複雑な式に対するアーギュメントとして用いることができます。以 下の例において、(* 2 4) は関数 + に対する 2番目のアーギュメントになります。
(+ 5 (* 2 4)) => 13 (* (+ 1 2) (- 10 8)) => 6 (+ (+ foo foo) (+ (+ foo foo) (+ foo foo))) => 60
最後の例は、括弧がたくさんあるため、多少読みにくいかもしれません。括弧をなくす ことはできませんが、空白を加えて読みやすくすることはできます。 Lisp は(文字で ある)スペース、ニューライン、タブは本質的に同じであると考えます。それらはシン ボルを互いに区別するのに用いられます。そこで、それらを用い、式を(より)読みやす くすることができます。
以下のものは、(どれも)同じ Lisp 式を示しています。
(+ (+ foo foo) (+ (+ foo foo) (+ foo foo))) => 60
(+ (+ foo foo) (+ (+ foo foo) (+ foo foo))) => 60
(+ (+ foo foo) (+ (+ foo foo) (+ foo foo))) => 60
(+ (+ foo foo) (+ (+ foo foo) (+ foo foo))) => 60
Lisp プログラマは(通常) 2 番目と 3 番目のスタイルを好みます。 Lisp 式は(全て) 適切な形でフォーマットするよう薦めます。 Lisp モードの TAB コマンドは、このよ うに行をインデントするよう定義されています (TAB キーに対するバインディングを見 て下さい)。