Scheme修行15章
Scheme修行は毎章違う題材が出てきます。前の章の継続も面白かったけど今回のも面白い。
メモ等
- ここに来て初めてdefineで値に名前をつける。
- set!の読み方「セット、バン!」
- set!は値を返さない。defineと似たもの。Lispではsetq(セットキュー、説得)
- set!すると名前の参照を変更出来る。あたかもxが定義されてないときにdefineで名前をつけるように。
- lambdaの値部分に2つ式があるのはletやbeginと同じ。2番目の式(最後の式)の値を返す。
- 別々の関数で同じ名前に対してset!する衝突が起こりえる。それは困る。
- lambdaをletで囲む
- あたかも架空の名前x1をdefineしたかのよう
- 架空の名前の値はない。
- 架空の名前が何を表しているか覚えておかないといけない
- 16の戒律「(let...)で定義された名前に対してのみ、(set!...)を使うべし
- 大域的な名前にset!すると駄目
- 第17の戒律(予備版)
(let ( (x ...)) ...)に対して(set! x ...)を用いる際には
それらの間には少なくとも1つのlambdaを置くべし
- letとsetの間にlambdaを入れないで使っても何かを覚える役には経たない
- 第18の戒律「(set! x ...)はxが参照する値がもはや必要ないときにのみ使うべし」
- set!すると値への参照がなくなってしまうので。
- swapを例に
- letを使って名前をつけるとその値を参照するのに2通りの方法がある
感想
15章ではset!の使い方と破壊的代入の問題点を説明している感じがしました。
ふつーのプログラミング入門だと変数に値を入れるのが関数の定義よりも先に来ますよね。
Scheme手習い、Scheme修行ではアトムから始まって、すぐに関数を定義して、値は引数で取り、関数を組み合わせて抽象化し、わざわざ関数に名前をつけずともY Combinaterがあれば再帰が出来る事を示し、計算結果を覚えるためにletを使い、と、ここまで値にdefineで名前をつける必要がありませんでした。
set!の説明と問題点を示すためだけにdefineで値に名前をつけている気がします。
関数プログラミング的な考えが重用視されてるような感じをちょっと受けています。
次の章が楽しみです。set!の上手い使いどころを示してくれそうな感じ。
# ホワイトボード使ってやるのも楽しそうですね
※ところでこの章、試験なナニを書けない気がします。なので実行ログを残しました。
gosh> (define x (cons 'chicago (cons 'pizza '()))) x gosh> x (chicago pizza) gosh> (set! x 'gone) gone gosh> x gone gosh> (set! x 'skins) skins gosh> (define gourmet (lambda (food) (cons food (cons x '())))) gourmet gosh> x skins gosh> (cons x '()) (skins) gosh> (gourmet 'onion) (onion skins) gosh> (set! x 'rings) rings gosh> (gourmet 'onion) (onion rings) gosh> (define gourmand (lambda (food) (set! x food) (cons food (cons x '())))) gourmand gosh> (gourmand 'potato) (potato potato) gosh> x potato gosh> (gourmand 'rice) (rice rice) gosh> x rice gosh> (define diner (lambda (food) (cons 'milkshake (cons food '())))) diner gosh> (define dinerR (lambda (food) (set! x food) (cons 'milkshake (cons food '())))) dinerR gosh> (dinerR 'onion) (milkshake onion) gosh> x onion gosh> (dinerR 'pecanpie) (milkshake pecanpie) gosh> x pecanpie gosh> (gourmand 'onion) (onion onion) gosh> (define omnivore (let ((x 'minestrone)) (lambda (food) (set! x food) (cons food (cons x '()))))) omnivore gosh> 'minestrone minestrone gosh> (omnivore 'bouillabaisse) (bouillabaisse bouillabaisse) gosh> (define gobbler (let ((x 'minestrone)) (lambda (food) (set! x food) (cons food (cons x '()))))) gobbler gosh> (gobbler 'gumbo) (gumbo gumbo) gosh> (define nibbler (lambda (food) (let ((x 'donut)) (set! x food) (cons food (cons x '()))))) nibbler gosh> (nibbler 'cheerio) (cheerio cheerio) gosh> (define food 'none) food gosh> (define glutton (lambda (x) (set! food x) (cons 'more (cons x (cons 'more (cons x '())))))) glutton gosh> (glutton 'garlic) (more garlic more garlic) gosh> food garlic gosh> x onion gosh> (define chez-nous (lambda () (set! food x) (set! x food))) chez-nous gosh> food garlic gosh> x onion gosh> (chez-nous) onion gosh> food onion gosh> x onion gosh> (define chez-nous (lambda () (let ((a food)) (set! food x) (set! x a)))) chez-nous gosh> (glutton 'garlic) (more garlic more garlic) gosh> food garlic gosh> (gourmand 'potato) (potato potato) gosh> x potato gosh> (chez-nous) garlic gosh> food potato gosh> x garlic gosh>
リポジトリの方にもcommitしてるのですが、外出先からPDA Net使ってgit pushしようとしたのですが繋がらないため、GitHubの同期はちょっと遅れてしまいそうです。ごめんなさい。