SICP問題4.26
unless の実装。unlessをifに変換するように実装する
追加する手続き
(define (unless? exp) (tagged-list? exp 'unless)) (define (unless-predicate exp) (cadr exp)) (define (unless-consequent exp) (caddr exp)) (define (unless-alternative exp) (if (not (null? (cdddr exp))) (cadddr exp) 'false)) ;; make-ifはcond->ifで定義済 (define (unless->if exp) (make-if (unless-predicate exp) (unless-alternative exp) (unless-consequent exp)))
analyzeの修正
(define (analyze exp) (cond ((self-evaluating? exp) (analyze-self-evaluating exp)) ((quoted? exp) (analyze-quoted exp)) ((variable? exp) (analyze-variable exp)) ((assignment? exp) (analyze-assignment exp)) ((definition? exp) (analyze-definition exp)) ((if? exp) (analyze-if exp)) ((unless? exp) (analyze (unless->if exp))) ;; 追加 ((lambda? exp) (analyze-lambda exp)) ((let? exp) (analyze (let->combination exp))) ((begin? exp) (analyze-sequence (begin-actions exp))) ((cond? exp) (analyze (cond->if exp))) ((application? exp) (analyze-application exp)) (else (error "Unknown expression type -- ANALYZE" exp))))
実験
;;; M-Eval input: (define (factorial n) (unless (= n 1) (* n (factorial (- n 1))) 1)) ;;; M-Eval value: ok ;;; M-Eval input: (factorial 5) ;;; M-Eval value: 120
OK
unless が特殊形式でなく手続きのままの方が良い場合は?
map等の高階関数の引数として使える場合。