blog/content/post/2008/08/31/2008-08-31-00001016.md

187 lines
6.5 KiB
Markdown
Raw Normal View History

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">&#62;</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', '高階関数 &#8211; Wikipedia');" target="_blank">高階関数 &#8211; 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さんにコメントいただいた &#8211; 武蔵の日記');" target="_blank"> Lispの引数についてid:SaitoAtsushiさんにコメントいただいた &#8211; 武蔵の日記</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', ' 手続き中の引数の書き方がわからないかもしれない &#8211; 武蔵の日記');" target="_blank"> 手続き中の引数の書き方がわからないかもしれない &#8211; 武蔵の日記</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>
</div>