結城浩のSICP日記 RSSフィード

2006-04-30

[]1.2.1: equal? 1.2.1: equal? - 結城浩のSICP日記 を含むブックマーク

factorialを作ろうと思って目を閉じて(は嘘、テキストを閉じて)書いていたらエラー出しまくりでした。

(define (factorial n)
  (if ((== n 0) 1)
      (else (* n (factorial (- n 1))))))
(factorial 10)

↑ではunbound variable: ==というエラーになる。

(define (factorial n)
  (if ((= n 0) 1)
      (else (* n (factorial (- n 1))))))
(factorial 10)

↑ではinvalid application: (#f 1)というエラーになる。

試行錯誤の末、書いたのが↓のコード。

(define (factorial n)
  (cond ((equal? n 0) 1)
        (else (* n (factorial (- n 1))))))

(factorial 10)

ifを使う場合は↓。condとレベルが少し違う。

(define (factorial n)
  (if (equal? n 0)
      1
      (* n (factorial (- n 1)))))

(factorial 10)
  • condとifが頭で混乱していた。
  • 識別子に?を付けるのがまだ慣れない。
  • equal?よりも=のほうがよいのかな? …と思ったときに何を調べればよいのだろう。R5RSかな?

R5RSを調べてみた。=は数の比較、eq?は厳しく、equal?は甘くという感じかな。

  • R5RSでは「同じく印字されたらequal?は真」とありますね。
  • 厳密には「数やシンボルに対してはeqv?を再帰的に適用したのがequal?」と。
gosh> (eq? 'a 'a)
#t
gosh> (equal? 'a 'a)
#t
gosh> (eq? '(a) '(a))
#f
gosh> (equal? '(a) '(a))
#t
gosh> (= '(a) '(a))
*** ERROR: real number required: (a)
Stack Trace:
_______________________________________
  0  (= '(a) '(a))
        At line 6 of "(stdin)"
  1  (= '(a) '(a))
        At line 6 of "(stdin)"

factorialの場合には数だから=が妥当か。

shiroshiro2006/04/30 17:25> プロンプトが邪魔
一応、このおまじないを打ち込むとカスタマイズできます。
gosh> (read-eval-print-loop #f #f #f (lambda () (display "$ ") (flush)))
$ 'a ;; <-- ここからプロンプトが "$ " になる
a
$ 'b
b
$ 'c
c
プロンプトを消したければ
gosh> (read-eval-print-loop #f #f #f (lambda () #f))
'a
a
'b
b
'c
c

shiroshiro2006/04/30 20:49多値が生成された場合、printerは複数の引数を受け取ることに注意して下さい。SICPの範囲では多値は出てこないと思いますが。