SICP 問題 4.52
利用者が失敗を捉えることができるif-failを実装する.
(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)) ((permanent-assignment? exp) (analyze-permanent-assignment exp)) ((definition? exp) (analyze-definition exp)) ((amb? exp) (analyze-amb exp)) ((ramb? exp) (analyze-ramb exp)) ((if? exp) (analyze-if exp)) ((if-fail? exp) (analyze-if-fail 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)))) (define (if-fail? exp) (tagged-list? exp 'if-fail)) (define (analyze-if-fail exp) (let ((proc (analyze (cadr exp))) (fail-proc (analyze (caddr exp)))) (lambda (env succeed fail) (proc env succeed (lambda () (announce-output output-prompt) (user-print (fail-proc env succeed fail)) (driver-loop))))))
test
;;; Amb-Eval input: (if-fail (let ((x (an-element-of '(1 3 5)))) (require (even? x)) x) 'all-odd) ;;; Starting a new problem ;;; Amb-Eval value: 'all-odd ;;; Amb-Eval input: (if-fail (let ((x (an-element-of '(1 3 5 8)))) (require (even? x)) x) 'all-odd) ;;; Starting a new problem ;;; Amb-Eval value: 8