Scheme事始め8:プログラム言語としてのSchemeのルール

  • Schemeの基礎
    • すべては()表記する(Listで表す)。自然数もListで表す
    • 関数は「ただの関数」というラムダ関数
    • カリー化は変数を1つずつ扱う方法で()だけで実現できる
    • ベータ簡約・イータ変換・ベータ正規形が関数の同等性や計算手続きの計算機実行を保証するとともに、プログラムの実装方法にルールを与える
  • これらのScehmeの基礎があればプログラムは書けるのだが、さすがにそれだけだと書く気が起きないので、いくつかの決め事が登場する
    • 少なければそれだけ覚えることはすくないし、計算機に近いが、繰り返し作業や、『言わなくてもわかるでしょ、人間なら』という部分が肥大化する
    • 多ければ便利だが、覚えないといけないし、作った決め事間の整合性に気を遣う必要が出る
  • 特殊形式
    • define
      • lambda関数を手軽に定義することができる
    • lambda
      • ラムダ関数
    • let
      • 対応付け??
    • quote
      • ただの引用
    • set!
      • 定義し直し、強制上書き
    • if
      • 真偽で2分岐
  • ひたすら例をなぞってたたいてみよう
> a
2.3
> (* 2 a)
4.6
> (define f_2x+3
    (lambda (x)
      ((lambda (a b)
         (+ (* a x) b)) 2 3) ))
> (f_2x+3 5)
13
> (define f_2x+3
    (lambda (x)
      (let ((a 2) (b 3))
        (+ (* a x) b))))
> (f_2x+3 5)
13
> (quote Gauss)
gauss
> (quote (+ 2 3))
(+ 2 3)
> (eval (quote (+ 2 3)) (interaction-environment))
5
  • Listからの要素取り出し
> (car (list + - * /))
#<procedure:+>
> (cadr (list + - * /))
#<procedure:->
> (caddr (list + - * /))
#<procedure:*>
> (cadddr (list + - * /))
#<procedure:/>
> ((car (list + - * /)) 5 3)
8
> ((cadr (list + - * /)) 5 3)
2
> ((caddr (list + - * /)) 5 3)
15
> ((cadddr (list + - * /)) 5 3)
1 2/3
  • 「そのままのquote」はしばしば使うので便利になっている
> (cons (quote b) (quote ()))
(b)
> (cons (quote a) (cons (quote b) (quote ())))
(a b)
> '(+ 2 3)
(+ 2 3)
> (list 'a 'b 'c)
(a b c)
> (append '(a b) '(c d))
(a b c d)
  • カウンタ
> (define count
    (lambda ()
      (set! n (+ n 1))))
> (define n 0)
> (count)
> n
1
> (count)
> n
2
> (count)
> n
3
    • 内部使用のnのカウンタは大域のnの値を変えずにカウンタ機能を内部で発揮
> (define count
    ((lambda (n)
       (lambda () (set! n (+ n 1))))
     0))
> (count)
> n
3
> (count)
> n
3
> (if (> 5 3)
      "yes"
      "no")
"yes"
> (define fact
    (lambda (n)
      (if (zero? n)
          1
          (* n (fact (- n 1))))))
> (fact 3)
6