プログラミングGauche 7章と8章

7.5 可変長手続きを返す

"続きを返す手続き"は、一部だけ違う手続きを複数記述する必要がある際に便利。
例えば、ある手続きを行う前に、引数の値を表示してから処理を行う手続きを書く際など。

本にある、make-loggerは、一度間違ったが、そらで書けた。

gosh> (define (make-logger func)
(lambda args
(print "args=" args)
(apply func args)))


gosh> ((make-logger cons) 1 2)
args=(1 2)
(1 . 2)


手続きを返す手続きを書けるといのは、Schemeを知る前には、なかった感動。

7.9.1 多値を受け取る

let-valuesと、let*-valuesの違いは、
let*-valuesの方は、変数のリスとの長で定義された変数を参照する。
let-valuesは参照せず、その時の環境の値で結果が変わる。

多値を返し、多値を受け取る

gosh> (define (hoge)
(values 'a 'b))
hoge
gosh> (let-values (((c d) (hoge)))
(print c)
(print d))
a
b
#


8.2 等価性

Javaの == と、equalsメソッドは、それぞれ、eq?と、equals?にあたる。

gosh> (eq? '(1 2) '(1 2))
#f
gosh> (equal? '(1 2) '(1 2))
#t
gosh> (define p '(a b))
p
gosh> (eq? p p)
#t
gosh> (equal? p p)
#t


8.4 条件判断

練習問題

いくつかの述語を引数にとり、新たな述語を作れ
・引数がもとの述語のどれかを満たせば真を返す any-pred
・引数がもとの述語のすべてを満たせば真を返す every-pred

gosh> (define (every-pred a b)
(lambda (x)
(and (a x)
(b x))))
every-pred
gosh> ((every-pred integer? positive?)
-4)
#f
gosh> ((every-pred integer? positive?)
4)
#t

gosh> (define (any-pred a b)
(lambda (x)
(or (a x)
(b x))))
any-pred

gosh> (any-pred integer? positive?)
#
gosh> ((any-pred integer? positive?) 8)
#t
gosh> ((any-pred integer? positive?) -8)
#t
gosh> ((any-pred integer? positive?) -2.4)
#f


引数が二つバージョンしか考え付かず。
無名関数をを再帰的に呼び出す方法が分かってれば、
述語をリストとして扱い、再帰的に実行できると思う。

、、、と思ったが、ローカルで手続きを書けばいいのだと9章のdelete-1を見て気づき、再実装

gosh> (define (every-pred . preds)
(lambda (x)
(define (loop x preds)
(if (pair? preds)
(if ((car preds) x)
(loop x (cdr preds))
#f)
#t))
(loop x preds)))
every-pred
gosh> ((every-pred integer? positive?)
4)
#t
gosh> ((every-pred integer? positive?)
-1)
#f


any-prefは読んでいる方へ宿題とします。

コメント

人気の投稿