Hatena::ブログ(Diary)

(define -ayalog ’()) このページをアンテナに追加 RSSフィード

2011-12-12

cond…

ちょっと朝から勉強してたので、今の理解している範囲を書きだしておく。

Scheme手習いではifなんて書かれることがない。
ほとんどcondで書かれている。あまり気にすることもないのかなぁと思っていたが、Scheme手習いの説明と実際のcondの役目というのは若干違っていて、そのScheme手習い的にはそれなりにSchemeについて知っているのが前提となっているような説明(もしくは自分で調べる必要があるような説明)がされている。
(少なくとも今3章まで読んだがcondに関する記述なんて0に近かった。)

Scheme手習い中のcondの説明としては十分なものは無く、define・lambdaと並べて使われるような約束事のようなものという認識だった。
つまり、define・lambdaと書いたらcondと書かないといけませんよーみたいな印象を受けたわけだ。
これは決して僕の頭が悪いからではないと思う。実際そういうように書いてある気がする。
だからScheme手習いを最初に読むのを僕は勧めない。多少の知識を有してからあれは読むべきだ。

ということで、もうひとつのScheme入門的には以下のように書いてある。

(cond
  (predicate_1 clauses_1)
  (predicate_2 clauses_2)
    ......
  (predicate_n clauses_n)
  (else        clauses_else))

この式では、predicate_1 から順番に調べ、一致した条件式のところの節を評価します。 条件に一致しない節は評価されません。
clauses_i には複数の式を書くことができ、最後の式の値が返ってきます。 どの条件も成り立たないときは clauses_else の値が返ってきます。


曖昧記述です。
ちょっと後で調べてみようと思いますが、「一致した条件式のところの節を評価します」とあるけど複数HITした場合はどうなるのか。また、「clauses_i には複数の式を書くことができ、最後の式の値が返ってきます。」これの意味がよく分からない。最後の式が返ってくるとは…。

まぁ僕の勘違いポイントはここらへんにあって、SchemeというかLISPの特徴だと思うんだけど、"評価した式の値が返ってくる"って結構重要だと思うんです。
condはてっきり実行したら#tか#fしか返さないと不思議な勘違いをしていて、たとえば

(define member?
  (lambda (a lat)
    (cond
     ((null? lat) #f)
     (else
      (or (eq? (car lat) a) (member? a (cdr lat)))))))

と書いてあれば
((null? lat) #f)

はlatがnullなら#tなので#f返しなさいってことなんですね。

こんな感じで"評価した式の値を返す"ってすげぇとなってます。
おしまい。

(色々と頭悪くてごめんなさい。一生懸命勉強中です。)

valvallowvalvallow 2011/12/12 09:48 gosh起動して実際に試してみるといいですよ。

> 「clauses_i には複数の式を書くことができ、最後の式の値が返ってきます。」これの意味がよく分からない。最後の式が返ってくるとは…。

$ gosh
gosh> (cond (#t 1 2 3)(else "hoge"))
3
gosh> (cond (#f 1 2 3)(else "hoge" "fuga" "piyo"))
"piyo"
gosh> (cond (#t 1 2 3))
3
gosh> (cond (#t (+ 1 1)(+ 2 2)(+ 3 3)))
6


> 複数HITした場合はどうなるのか。

gosh> (cond (#t 1)(#t 2)(#t 3)(else 4))
1
gosh> (cond (#f 1)(#t 2)(#t 3)(else 4))
2

ayato0211ayato0211 2011/12/13 08:24 なるほど…。
ちなみに最後の式が返ってくるのが分からないと書きましたが、一致してるものは全て評価した上で最後の式の値が返ってくるということですよね?

valvallowvalvallow 2011/12/13 10:09 そういう時は、このように試してみるといいですよ。

gosh> (cond (#f 1 2 3)(else (print "hoge")(print "fuga") "piyo"))
hoge
fuga
"piyo"

gosh> (cond (#t (print 1)(print 2) 3)(else (print "hoge")(print "fuga") "piyo"))
1
2
3

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証