Swi prolog recently got predicate continuation and knowing of extearamly functional minkanren/microkanren is, one should be able to construct such a beast. Now in most languages you would need to make sure that a cach throw mechanism is working in the return values and somehow knit that together. But with scheme this feature lend itself beutifully to it's delimeted continuations, so what do we mean with a delimeted continuation presicate? well we could model it on prologs
;; Catching (catch-cont ball cont code handler) (define handler (lambda (k ball) code ...)) ;;throwing (throw ball return-ball) ;;use it as (define (f i n) (let lp ((i i)) (if (< i n) (conda ((throw i _) (lp (+ i 1)))))) fail) (define (print-all i) (pk i) (fresh (i) (catch-cont (list 'a i) (lambda () (k #f)) (lambda (kk ret) (fresh (i) (== (list _ i) ret) (print-all kk i)))))) ;; This will print out all number 0 - 9 (define (test) (fresh (i) (catch-cont (list 'a i) (lambda () (f 0 10)) (lambda (k ret) (fresh (i) (== (list _ i) ret) (print-all k i))))))
So we establish a catcher of the ball, if it unifies with the ball thrown, the handler would be executed with the ball as incomming.
Here is the minkanren code for this
(define (catch-cont ball codeThunk handler) (lambdag (c) (call-with-prompt catch-cont-id (lambda () (code c)) (lambda (k c2 ball2) (let ((c3 (copy-from-c2-onto-c c2 ball c))) ((conde ((== ball ball2) (let ((kk (lambda (return-ball) (lambda (c-ret) (k c-ret return-ball))))) (handler kk ball)))) c3)))))) (define (throw ball return-ball) (lambda (c) ((lambda (cret return-ball-2) (let ((c2 (copy-from-cret-onto-c cret return-ball-2 c))) ((== return-ball return-ball-2) c2))) (abort-to-prompt catch-cont-id c ball))))
Fun Fun Fun.