; Consider this simple program in the amb language ; (define (problem) ; (let ((x (amb 1 2 3 4 5))) ; (require (> x 2)) ; x)) ; What would this program look like if written directly in Scheme? ; 1. Using the contination idea explicitly (define (amb list succeed fail) (if (null? list) (fail) (succeed (car list) (lambda () (amb (cdr list) succeed fail))))) (define (filter val proc succeed fail) (if (proc val) (succeed val fail) (fail))) (define (success val fail) (display val) (newline) (display ">>") (let ((s (read))) (if (eq? s 'try-again) (fail) 'quitting))) (define (failure) (display "no more solutions") (newline)) (define (problem1) (amb '(1 2 3 4 5) (lambda (val fail) (filter val (lambda (val) (> val 2)) success fail)) failure)) ; without continuations (define (problem2) (do ((x 1 (+ x 1)) (done #f)) ((or done (> x 5)) (if (> x 5) (display "no more solutions") 'quitting)) (if (> x 2) (begin (display x) (newline) (display ">>") (let ((s (read))) (if (not (eq? s 'try-again)) (set! done #t))))))) ; Which version is easier to write and understand: ; problem, problem1 or problem2? ; Imagine how the three approaches would compare on larger problems.