[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends:00504] SICP 読書会 第17回議事録



こんにちは。鈴木@二村研です。

問題4.12ですが、一応やってみました。
共通化できるものの、コードは理解しづらいです。
動作確認も一応したので大丈夫だとおもいます。

以下議事録です。


第17回読書会@タイムインターメディア


次回読書会会場確保 1月26日
1 早稲田理工学部
2 タイムインターメディア


             やましたさん 横山さん
             ___________________
えんどうさん |                 |
             |                 |
和田先生     |                 |
             |                 |
             -------------------
             鈴木     保坂さん

p217
eval-sequenceは左から評価しているが、
elseで上手く並びを評価している。
(condでbeginを省略。)

p218 註釈8

MIT-Schemeでのset!,defineのふるまい

その1
1 ]=> (define a 3)
;Value: a
1 ]=> (set! a 100)
;Value: 3
1 ]=> a
;Value: 100

その2
1 ]=> (define a 5)
;Value: a
1 ]=> (define b 10)
;Value: b
1 ]=> (set! a (set! b a))
;Value: 5
1 ]=> a
;Value: 10
1 ]=> b
;Value: 5


ちゃんと交換できているので
テンポラリ変数を使わない分便利。

scmでのset!,defineのふるまい

その1
==> (define a 3)
a
==> (set! a 100)
100

その2
==> (define a 5)
a
==> (define b 10)
b
==> (set! a (set! b a))
5
==> a
5
==> b
5


p221 elseは特別扱い
1 ]=> (define else #f)

;Value: else

1 ]=> (cond ((= 1 2) 1) (else 100))

;Value: 100

1 ]=> (if else 1 2)

;Value: 2


;;p227
(define input-prompt ";;; M-Eval input:")

の "M-" は metacircularの "M"

第4章から

問題4.1

;;必ず左から評価するlist-of-values

(define (list-of-values exps env)
  (if (no-operands? exps)
      '()
      (let ((left (eval (first-operand exps) env)))
        (cons left (list-of-values (rest-operands exps) env)))))

;;; M-Eval input:
(cons ((lambda () (display "1") 1)) ((lambda () (display "2") 2)))
12
;;; M-Eval value:
(1 . 2)

;;必ず右から評価するlist-of-values

(define (list-of-values exps env)
  (if (no-operands? exps)
      '()
      (let ((right (list-of-values (rest-operands exps) env)))
        (cons (eval (first-operand exps) env) right))))

;;; M-Eval input:
(cons ((lambda () (display "1") 1)) ((lambda () (display "2") 2)))
21
;;; M-Eval value:
(1 . 2)


Schemeではapplicative-orderだからこれでもいいが、
normal-orderだとこれではだめ。


問題4.2

(a).
手続き作用 application? は,以下のような定義になっている.

(define (application? exp) (pair? exp))

これが代入節の前に来た場合,
代入節はこの application? に対して常に真を
返すので,本来の代入の文に対する処理を行なわなくなってしまう.


;;; M-Eval input:
(define x 3)

ERROR: Unbound variable -- LOOKUP-VARIABLE-VALUE define

(b).

application?の定義を変更して,
cond 節の一番上にapplication?を持ってきた.

(define (application? exp)
  (tagged-list? exp 'call))

(define (eval exp env)
  (cond ((application? exp)
         (apply (eval (operator exp) env)
                (list-of-values (operands exp) env)))
        ((self-evaluating? exp) exp)
        ((variable? exp) (lookup-variable-value exp env))
        ((quoted? exp) (text-of-quotation exp))
        ((assignment? exp) (eval-assignment exp env))
        ((definition? exp) (eval-definition exp env))
        ((if? exp) (eval-if exp env))
        ((lambda? exp)
         (make-procedure (lambda-parameters exp)
                         (lambda-body exp)
                         env))
        ((begin? exp) 
         (eval-sequence (begin-actions exp) env))
        ((cond? exp) (eval (cond->if exp) env))
        (else
         (error "Unknown expression type -- EVAL" exp))))


問題4.3

2.73のデータ主導微分プログラムは以下のとおり.

(define (deriv exp var)
  (cond ((number? exp) 0)
        ((variable? exp) (if (same-variable? exp var) 1 0))
        (else ((get 'deriv (operator exp)) (operands exp)
                                           var))))

(define (operator exp) (car exp))

(define (operands exp) (cdr exp))

こでにしたがってevalをデータ主導微分プログラムに変更すると,
(上の operator, operands 関数を用いて)

(define (eval exp env)
  (if (self-evaluating? exp)
      exp
      (let ((ret (get 'eval (operator exp))))
	(if ret
	    (ret (operands exp) env)
	    (if (application? exp)
		(apply (eval (operator exp) env)
		       (list-of-values (operands exp) env))
		(error "ERROR -- EVAL " exp))))))

と変更することができる.

問題4.4

and,or で評価したとき、式の値を返すというところが、
どうも気に入らないという意見も。

問題4.5

;;; M-Eval input:
(cond ((assoc 'b '((a 1) (b 2))) => cadr)
      (else false))
;;; M-Eval value:
2

問題4.6

;;; M-Eval input:
(let ((x 1)
      (y 2))
  (cons x y))
;;; M-Eval value:
(1 . 2)


問題4.7
;;; M-Eval input:
(let* ((x 3)
       (y (+ x 2))
       (z (+ x y 5)))
  (list x y z))


;;; M-Eval value:
(3 5 13)

問題4.8

(define (fib n)
  (let fib-iter ((a 1)
		 (b 0)
		 (count n))
    (if (= count 0)
	b
	(fib-iter (+ a b) a (- count 1)))))

問題4.9
;;; M-Eval input:

(do ((i 0 (+ i 1))
     (j 0 (+ j 2)))
    ((= i 10) nil)
    (display j) (newline))

0
2
4
6
8
10
12
14
16
18

;;; M-Eval value:
#f

問題4.10
後置記法に対応させるために
tagged-list?, operator, operands
などを変更するということ。

問題4.11

(define (add-binding-to-frame var val frame)
  (cons (list var val) frame))

(define (define-variable! var val env)
  (let ((frame (first-frame env)))
    (let ((result (assoc var frame)))
      (if (null? result)
          (set-car! env (add-binding-to-frame var val frame))
          (set-car! (cdr result) val)))))

問題4.12

(define (foo var val env step1 step2 step3)
  (if (eq? env the-empty-environment)
      (step1 var val env)
      (let ((frame (first-frame env)))
	(let ((result (assoc var frame)))
	  (if (null? result)
	      (step2 var val env frame result)
	      (step3 var val env frame result))))))

(define (define-variable? var val env)
  (foo var val env
       (lambda (var val env) nil)               ;;絶対起こらない
       (lambda (var val env frame result)
	 (set-car! env (add-binding-to-frame var val frame)))
       (lambda (var val env frame result)
	 (set-car! (cdr result) val))))

(define (set-variable-value! var val env)
  (foo var val env
       (lambda (var val env)
	 (error "UNbound variable -- SET-VARIABLE-VALUE!" var))
       (lambda (var val env frame result)
	 (set-variable-value! var val (enclosing-environment env)))
       (lambda (var val env frame result)
	 (set-car! (cdr result) val))))

(define (lookup-variable-value var env)
  (foo var nil env
       (lambda (var val env)
	 (error "Unbound variable -- LOOKUP-VARIABLE-VALUE" var))
       (lambda (var val env frame result)
	 (lookup-variable-value var (enclosing-environment env)))
       (lambda (var val env frame result)
	 (cadr result))))

問題4.13
;;; M-Eval input:
(define x 100)

;;; M-Eval value:
ok

;;; M-Eval input:
x

;;; M-Eval value:
100

;;; M-Eval input:
(undef! x)

;;; M-Eval value:
#<unspecified>

;;; M-Eval input:
x

ERROR: Unbound variable -- LOOKUP-VARIABLE-VALUE x

問題4.14

(define (my-map func lst)
  (if (null? lst)
      false
      (cons (func (car lst)) (my-map func (cdr lst)))))

(my-map (lambda (x) (+ x 1)) '(1 2 3 4 5))

Louisの言ったようにやると、
;;; M-Eval input:
(map (lambda (x) (+ x 1)) '(1 2 3 4 5))

ERROR: map: Wrong type in arg1 (procedure (x) ((+ x 1)) (((my-map (procedure (func lst ...
==> (driver-loop)
;;; M-Eval input:
(map car '((a 1) (b 2) (c 3)))

ERROR: map: Wrong type in arg1 (primitive #<primitive-procedure car>)


問題4.15
(halts? try try) がとまると判断するなら -> 最初によんだ(try try)はとまらない。
(halts? try try) がとまらないと判断するなら -> 最初によんだ(try try)はとまる。

というわけで矛盾。

次回はいままでやった分の復習から

------------------------------------------------------------------------
         ★ こっちの流行語大賞はどんなの?          
  http://www.infoseek.co.jp/Keyword?pg=nranking_top_if.html&svx=971122