[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bep] learning lisp: if, and, cond



n高橋です。

Reiko TAKAHASHI  (高橋玲子)writes:

> ところで、Lispを書くときの字下げ?(indentation)には、なにか決まりのよう
> なものはありますか?

一応ガイドラインのようなものはありますが、読みやすければ何でもいいと思
います。原則は、

・深いレベルの要素ほど下げる
・同じレベルの要素は同じだけ下げる

です。まあ他人のプログラムを読んでいるうちに自然とわかってくると思いま
す。defun の直前の開き括弧の上にカーソルを置いて M-q とすると自動的に
インデントされますが、それが Emacs のおすすめ indentation です。

> >= のヘルプの中に、
> Both must be numbers or markers.
> と書かれているのですが、"markers"ってなんですか?

これはいきなり難しいことを聞いてきましたね。
marker っていうのはバッファ内の位置を示すためのものです。普通、バッファ
内の位置は整数で表します。たとえば (char-after 1) とすると、現在のバッ
ファの先頭の文字が返され、(char-after 100) とすると先頭から100番目の文
字が返されます。

まあ普通はこれでいいんですが、ここでたとえば50番目の文字を消したりする
と、(char-after 100) は以前101番目だった文字を返すことになります。とこ
ろが場合によっては、途中で挿入や削除があっても最初に100番目だった場所
を常にトレースしたい場合があります。marker はそういう時に使います。
marker を作ってそれにバッファ内の位置を束縛(代入)すると、間に挿入や削
除があっても marker の示す位置は自動的に調整されるようになります。

わからなかったら、とりあえずは忘れていいと思います。(^_^)

> } (setq x 5)
> } (and nil (setq x 6))
> } 
> } とした後でxの値を調べても5のままになっています。

>  はい、これはわかりました。↑の nil もずるい感じの nil ですね(^_^)。

たしかに普通はこんな使い方はしません。あくまでも説明の都合上です。

> } cond の一般形は次のような形をしています。

> (not ...) というのもあるんですね。

はい。意味は自明ですよね。

> } 最後の「条件4」の t がちょっとわかりにくいかもしれません。上で書いたよ
> } うに、cond は条件xが真になったところでそれ以降の条件のチェックをとばし
> } ます。ということは、もし「条件4」のところまで来たのならば、
> } 
> } ・nは整数でなくなく(つまり整数)、
> } ・かつ1より小さくなく(つまり1以上)、
> } ・しかも1でない、
> } 
> } ということになります。わかりやすく言うと、nは1よりも大きい整数だという
> } ことになります。nが1よりも大きな整数であれば、そのときの答はnの値にか
> } かわらず (* n (fact (1- n))) です。ですから「条件4」を t (つまり真)
> } としておいて、常に (* n (fact (1- n))) を返すようにしているわけです。

>  これも、「ずるい」tっぽい? もう絶対に t だとわかっているので、なんと
> 条件式のところに、最初から t を入れてしまう、ということですよね。

単に言葉使いの問題かもしれませんが、「もう絶対に t だとわかっている」
というと消極的な感じがします。むしろ、「プログラマである俺様がこれ以降
は全部こうすることに決めたんだ」という主張だと考えた方がいいかもしれま
せん。

> } cond を書くときは以上のように、まず例外的な場合を取り出し、最後に「そ
> } れ以外なら」という意味で t という条件を置くのが普通です。もちろん Lisp
> } は nil 以外をすべて真ととらえますから、t の変わりに 1 とか 'a とか
> } "hello" とか書いてもいいんですが、わかりやすさのため t を使うのが習慣
> } です。
> } 
> } なお、cond の条件の最後が t でなく、かつすべての条件が nil となった場
> } 合、cond 自身の値も nil となります。

>  「cond の条件の最後が t でなく」というのは、「nil だったら」という意味
> ですか?

違います。たとえばこんな例を考えます。

(defun season (n)
  (cond
   ((not (integerp n))
    (print "Argument must be an integer")
    nil)
   ((= n 1) 'spring)
   ((= n 2) 'summer)
   ((= n 3) 'autumn)
   ((= n 4) 'winter)))

最初の (not (integerp n)) は fact の場合同様、整数かどうかのチェックで
す。それより後ろは、1〜4の引数を春夏秋冬に変換する部分です。ここで最後
の条件が t になっていません。ですから引数として1〜4以外の整数を与える
とマッチする条件が一つもないことになります。この場合 cond は nil を返
しますから、season の値も nil になります。

もし最後の行を
 
   (t 'winter)))

に変えると、1〜3以外の引数は全部 winter になります。違いがおわかりでしょ
うか。

-- 
TAKAHASHI Naoto
ntakahas@...
http://www.m17n.org/ntakahas/