SICPを読む(48) 2.2.1(3) map
とうとうmapが出てきた。mapは,perlやruby等にもある結構有名な関数。僕はforeachやeachを使っていたので、mapを使用することは殆ど無かった気がする。Schemeのmapを使うことで何かが変わるのだろうか?
map
(define (map proc items) (if (null? items) `() (cons (proc (car items)) (map proc (cdr items))))) (map (lambda (x) (* x x)) (list 1 2 3 4)) ; (1 4 9 16)
リスト全てにprocを適用できる。ふむふむ。
mapなら、「リストに何をするのか」を書くだけで良い。インデックスが・・・と考える必要が無くなるので。
mapを使う → プログラムがすっきりする → 見通しが良くなる → 更に高い抽象 → ウマー
となる(はず)
脚注のmapが凄い
凄かったのが脚注のmap。
(map + (list 1 2 3) (list 4 5 6) (list 7 8 9)) ; (12 15 18)
なんじゃこら〜〜〜〜〜〜〜〜〜〜〜〜!!
こんな発想全然無かったよ・・・。
階層構造は次節に出てくるので、次節で本物のmapを作ってみようと思う。
僕のschemeレベル
僕のschemeレベルを確認しておこう。
レベル3
- mapの便利さに目覚めて、なんでもかんでもリストにしてからmapしまくる。 letrecやinternal defineによるローカル関数定義を多用するようになる。
- 自分のwebサイトのドキュメントをSchemeを使ったフィルタで生成するとか、普段から使える個人用のプログラムをSchemeで書き始める。後に、そのコードの半分はsrfi-1とsrfi-13にある関数の再実装であったことに気づく。
- call/ccを非局所脱出やコルーチンに使ってみて、なるほど、確かに動くな、と思うが、それ以上の応用は思い浮かばない。
- 普段常用するマシンに色々な処理系をインストールしまくる。
- たまにC言語に戻った時に printf("%s: %d?n" name value); と書いて何故コンパイルエラーになるのか悩む。
- mapを覚えた,let多用気味になりそう。
- let, let*, letrec letrecで再帰できるlambdaが作れる。ほうほう。なるほど。letrecも多用しよう〜。
- Schemeを使ったフィルタで生成はやってない。
- 普段から使える個人用のプログラム - ボチボチやり始めた。
- コルーチンのサンプルコピペしたり(でも継続はわからず)
- 処理系をインストールしまくったり
- printf("%s: %d?n" name value);って何か間違ってますか?
レベル2.8くらいまで到達したきがする。mapしまくるぞぉ〜〜〜。