2019-03-31 11:00:21 +00:00
---
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
---
< div class = "section" >
< blockquote >
< p >
「手続き」は、数値、文字列、真偽値と同様、「値」として他の変数に束縛したり、引数として他の手続きに渡したり、他の手続きの戻り値として返したりできます。
< / p >
< / blockquote >
< p >
ここらへんはややトリッキーだけど、Cとかでも関数ポインタとかあったはず。Javaとかだと、オブジェクト型を渡していたりするから、そこらへんと同じ感じなんだろう…と思う。
< / p >
< h4 >
foldってトリッキー
< / h4 >
< pre class = "syntax-highlight" >
< span class = "synSpecial" > (< / span > define < span class = "synSpecial" > (< / span > print_element lis< span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (</ span > fold < span class = "synSpecial" > (</ span >< span class = "synStatement" > lambda</ span > < span class = "synSpecial" > (</ span > a b< span class = "synSpecial" > )</ span > < span class = "synSpecial" > (</ span >< span class = "synStatement" > print</ span > a< span class = "synSpecial" > ))</ span > #f lis< span class = "synSpecial" > ))</ span >
< / pre >
< p >
foldは順番にlisを処理する。ちなみに「(lambda (a b) (print a)」という無名関数への引数は順番に次のようになるよ( lisが「(1 2 3 4 5)」の場合):
< / p >
< table >
< tr >
< th >
第一引数
< / th >
< th >
第二引数
< / th >
< / tr >
< tr >
< td >
1
< / td >
< td >
#f
< / td >
< / tr >
< tr >
< td >
2
< / td >
< td >
1
< / td >
< / tr >
< tr >
< td >
3
< / td >
< td >
2
< / td >
< / tr >
< tr >
< td >
4
< / td >
< td >
3
< / td >
< / tr >
< tr >
< td >
5
< / td >
< td >
4
< / td >
< / tr >
< / table >
< p >
となることに注意。なんか自分の直感に反している。
< / p >
< h4 >
ようやく自分が何が理解できていないのかわかった!
< / h4 >
< p >
「高階手続き」がわかっていないんだ!これをキーワードに勉強していこう!
< / p >
< h4 >
高階手続き(Wikipediaから)
< / h4 >
< blockquote title = "高階関数 - Wikipedia" cite = "http://ja.wikipedia.org/wiki/%E9%AB%98%E9%9A%8E%E9%96%A2%E6%95%B0" >
< p >
関数を戻り値とする関数
< / p >
< pre class = "syntax-highlight" >
< span class = "synSpecial" > (< / span > define < span class = "synSpecial" > (< / span > add x y< span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > < span class = "synStatement" > +< / span > x y< span class = "synSpecial" > ))< / span > < span class = "synError" > ))< / span >
< / pre >
< p >
このaddを次のように書き直す
< / p >
< pre class = "syntax-highlight" >
< span class = "synSpecial" > (< / span > define < span class = "synSpecial" > (< / span > add x< span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > < span class = "synStatement" > lambda< / span > < span class = "synSpecial" > (< / span > y< span class = "synSpecial" > )< / span > < span class = "synSpecial" > (< / span > < span class = "synStatement" > +< / span > x y< span class = "synSpecial" > )))< / span >
< / pre >
< p >
これを使って加算をするには、次のように書く。
< / p >
< pre class = "syntax-highlight" >
< span class = "synStatement" > > < / span > < span class = "synSpecial" > ((< / span > add < span class = "synConstant" > 2< / span > < span class = "synSpecial" > )< / span > < span class = "synConstant" > 3< / span > < span class = "synSpecial" > )< / span >
< span class = "synConstant" > 5< / span >
< / pre >
< p >
ここで、まず(add 2)の戻り値は1つ引数をとって2を足す関数になる。そして、戻り値として返ってきた関数に、更に3を渡して最終的な計算結果を得ている。つまり、add自身は関数を戻り値とする高階関数となっている。 上記のような、n引数ある関数を、1引数だけの高階関数に変換する操作をカリー化と呼ぶ。
< / p >
< p >
< cite > < a href = "http://ja.wikipedia.org/wiki/%E9%AB%98%E9%9A%8E%E9%96%A2%E6%95%B0" onclick = "__gaTracker('send', 'event', 'outbound-article', 'http://ja.wikipedia.org/wiki/%E9%AB%98%E9%9A%8E%E9%96%A2%E6%95%B0', '高階関数 – Wikipedia');" target = "_blank" > 高階関数 – Wikipedia< / a > < / cite >
< / p >
< / blockquote >
< p >
なんかよくわからなかったんだけど、わかった瞬間がきた!
< / p >
< h4 >
つまり
< / h4 >
< pre class = "syntax-highlight" >
< span class = "synSpecial" > (< / span > define < span class = "synSpecial" > (< / span > reversed walker< span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > < span class = "synStatement" > lambda< / span > < span class = "synSpecial" > (< / span > proc lis< span class = "synSpecial" > )< / span >
< span class = "synSpecial" > (< / span > walker proc < span class = "synSpecial" > (< / span > < span class = "synStatement" > reverse< / span > lis< span class = "synSpecial" > ))))< / span >
< / pre >
< p >
のreversedという手続きは「一つ引数をとって、戻り値として二つの引数をとる手続きを返す」ってことなんだ! ( 間違えてない…はず。大丈夫だよね。。。)
< / p >
< blockquote >
< ul >
< li >
「gauche」に関連する最近のエントリ < ul >
< li >
< a href = "http://d.hatena.ne.jp/sirocco634/20080830/1220052100" onclick = "__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20080830/1220052100', ' Lispの引数について( id:SaitoAtsushiさんにコメントいただいた) – 武蔵の日記');" target = "_blank" > Lispの引数について( id:SaitoAtsushiさんにコメントいただいた) – 武蔵の日記< / a >
< / li >
< li >
< a href = "http://d.hatena.ne.jp/sirocco634/20080828/1219931251" onclick = "__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20080828/1219931251', ' 手続き中の引数の書き方がわからないかもしれない – 武蔵の日記');" target = "_blank" > 手続き中の引数の書き方がわからないかもしれない – 武蔵の日記< / a >
< / li >
< li >
< a href = "http://d.hatena.ne.jp/sirocco634/20080825/1205475020" onclick = "__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20080825/1205475020', '武蔵の日記');" target = "_blank" > 武蔵の日記< / a >
< / li >
< / ul >
< / li >
< / ul >
< / blockquote >
2019-04-02 16:06:15 +00:00
< / div >