exceptionschemecallcc

How to make the function in a lambda be called in another function used inside the body of lambda


I want to using call/cc to simulating the exception handling statement: try...(throw)...exception. Here's the code:

(define (month n) ; check if it's a month number (1-12)
  (if (or (not (integer? n)) (< n 1) (> n 12))
    (throw -1)
    (display n)
  )
)

(define error (call/cc
   (lambda(throw)
     (begin
       (month 12)
       (month -1)
       (throw -1) ; won't be executed
       (month 10)
       (display "Hello world")
      )
     )
   )
 )

(if error
  (display Error occured!")
)

However, When I executed it, it showed the error (in biwascheme):

Error: execute: unbound symbol: "throw" [(anon), month]

I think that the throw in lambda is not the same as the throw in the called function "month", However, how can I solve it? Is it can be solved with making marco with some keywords? eg:

(define-syntax exception-handling
    (syntax-rules (throw raise error)
      ((_ body catch)
        (define (error
                  (call/cc (lambda (throw) (begin body))))
        )
        (if error (begin catch)))
    )
 )

Solution

  • In Scheme, continuations are first-class. A captured continuation is just another value. Pass it in to your month function as another argument:

    (define (month n throw) ; check if it's a month number (1-12)
      (if (or (not (integer? n)) (< n 1) (> n 12))
        (throw -1)
        (display n)))
    

    And call it as

         ....
         (month 12 throw)
         ....
         (month 10 throw)
         ....
    

    Your indentation style is not conducive to the readability of your code.