56 lines
1.1 KiB
Text
56 lines
1.1 KiB
Text
|
;; call/cc 的型別: (forall (A B C) in Any) (-> (-> (-> A C) B) (U A B))
|
||
|
|
||
|
|
||
|
;; 異常處理 call/cc
|
||
|
https://csl.name/post/lambda-macros-continuations/
|
||
|
(define-library (try-catch)
|
||
|
(import (scheme base)
|
||
|
(print))
|
||
|
|
||
|
(export
|
||
|
try)
|
||
|
|
||
|
(begin
|
||
|
(define-syntax try
|
||
|
(syntax-rules (catch)
|
||
|
((try
|
||
|
(exception-handler handler)
|
||
|
body ...
|
||
|
(catch exception-catcher))
|
||
|
(begin
|
||
|
(define handler (lambda (error) #f)) ; default: do nothing
|
||
|
(call/cc
|
||
|
(lambda (exit)
|
||
|
(set! handler
|
||
|
(lambda (error)
|
||
|
(exception-catcher error)
|
||
|
(exit)))
|
||
|
body ...))))))))
|
||
|
|
||
|
Example usage:
|
||
|
|
||
|
(import (scheme base)
|
||
|
(print)
|
||
|
(try-catch))
|
||
|
|
||
|
(println "--start--")
|
||
|
|
||
|
(try
|
||
|
(exception-handler oops)
|
||
|
|
||
|
(define (divide a b)
|
||
|
(if (zero? b)
|
||
|
(oops "Division by zero")
|
||
|
(println a "/" b " = " (inexact (/ a b)))))
|
||
|
|
||
|
(divide 10 2)
|
||
|
(divide 1 3)
|
||
|
(divide 3 0)
|
||
|
(println "This should not execute")
|
||
|
|
||
|
(catch
|
||
|
(lambda (error)
|
||
|
(println "Hey, we caught an error: " error))))
|
||
|
|
||
|
(println "--end--")
|