--- title: もう一度第七章をはじめから author: kazu634 date: 2008-08-31 wordtwit_post_info: - 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:4247;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}' categories: - gauche - Lisp ---
「手続き」は、数値、文字列、真偽値と同様、「値」として他の変数に束縛したり、引数として他の手続きに渡したり、他の手続きの戻り値として返したりできます。
ここらへんはややトリッキーだけど、Cとかでも関数ポインタとかあったはず。Javaとかだと、オブジェクト型を渡していたりするから、そこらへんと同じ感じなんだろう…と思う。
(define (print_element lis) (fold (lambda (a b) (print a)) #f lis))
foldは順番にlisを処理する。ちなみに「(lambda (a b) (print a)」という無名関数への引数は順番に次のようになるよ(lisが「(1 2 3 4 5)」の場合):
第一引数 | 第二引数 |
---|---|
1 | #f |
2 | 1 |
3 | 2 |
4 | 3 |
5 | 4 |
となることに注意。なんか自分の直感に反している。
「高階手続き」がわかっていないんだ!これをキーワードに勉強していこう!
関数を戻り値とする関数
(define (add x y) (+ x y))))このaddを次のように書き直す
(define (add x) (lambda (y) (+ x y)))これを使って加算をするには、次のように書く。
> ((add 2) 3) 5ここで、まず(add 2)の戻り値は1つ引数をとって2を足す関数になる。そして、戻り値として返ってきた関数に、更に3を渡して最終的な計算結果を得ている。つまり、add自身は関数を戻り値とする高階関数となっている。 上記のような、n引数ある関数を、1引数だけの高階関数に変換する操作をカリー化と呼ぶ。
なんかよくわからなかったんだけど、わかった瞬間がきた!
(define (reversed walker) (lambda (proc lis) (walker proc (reverse lis))))
のreversedという手続きは「一つ引数をとって、戻り値として二つの引数をとる手続きを返す」ってことなんだ!(間違えてない…はず。大丈夫だよね。。。)
- 「gauche」に関連する最近のエントリ