Resource > SICP Exersise 4_5
Exercise 4.5:
Exercise 4.5:
(define (cond-clauses exp) (cdr exp))
(define (cond-else-clause? clause)
(eq? (cond-predicate clause) 'else))
(define (cond-predicate clause) (car clause))
(define (cond-actions clause) (cdr clause))
(define (cond->if exp)
(expand-clauses (cond-clauses exp)))
;; clauses は 'cond を除いた条件文-アクションが並ぶ
(define (expand-clauses clauses)
(if (null? clauses)
'false ; no `else' clause
;; firstは一つ目の条件文とアクション
(let ((first (car clauses))
(rest (cdr clauses)))
(if (cond-else-clause? first)
(if (null? rest)
(sequence->exp (cond-actions first))
(error "ELSE clause isn't last -- COND->IF"
clauses))
(make-if (cond-predicate first)
;; 条件文の結果を sequence->expに渡す
(sequence->exp (cond-predicate first) (cond-actions first))
(expand-clauses rest))))))
(define (make-if predicate consequent alternative)
(list 'if predicate consequent alternative))
(define (sequence->exp value seq)
(cond ((null? seq) seq)
((last-exp? seq) (first-exp seq))
;; =>の場合はvalueを引数として手続きに渡す
((equal? '=> (first-exp seq)) (list (cadr seq) value))
(else (make-begin seq))))
(define (last-exp? seq) (null? (cdr seq)))
(define (first-exp seq) (car seq))
(define (make-begin seq) (cons 'begin seq))
(put 'eval 'cond (lambda(exp env) (eval (cond->if exp) env)))