Как ошибки PLTScheme Catch?

Я поражен функцией «ошибка» в PLTScheme. Если у меня деление на ноль, оно не выполняет никакой другой рекурсии, а просто выходит из стека вызовов и выдает мне ошибку.

Есть ли неявное продолжение перед всеми функциями? Ошибка выбрасывает стек вызовов? У кого-нибудь есть идеи по этому поводу?

13.10.2009 01:45:07
1 ОТВЕТ
РЕШЕНИЕ

В схеме PLT ошибка процедуры вызывает исключение exn: fail , которое содержит строку ошибки. Не существует «неявного улова» для всех определений. Посмотрите на следующий пример:

;; test.ss
(define (a d)
  (printf "~a~n" (/ 10 d)))

(a 0) ;; The interpreter will exit here.     
(printf "OK~n")

Выполните приведенный выше скрипт из командной строки, и вы увидите, что интерпретатор существует после печати чего-то вроде

/: division by zero

 === context ===
/home/user/test.ss:1:0: a

Если исключение не обрабатывается в пользовательской программе, оно передается основному интерпретатору, где с ним работает обработчик по умолчанию, то есть выводит исключение и завершается. Другими словами, переводчик просто говорит: «Возникло исключение, и я не знаю, как с ним бороться, поэтому я ухожу». Это не сильно отличается от того, как JVM или некоторые другие виртуальные машины обрабатывают исключения.

Чтобы узнать больше о механизме обработки исключений в PLT-схеме, ознакомьтесь с инструкциями with-handlers и dynamic-wind в руководстве по языку MzScheme . Используя их, вы даже можете эмулировать Java-блок try-catch-finally.

(define (d a b)
  (try
   (printf "~a~n" (/ a b))
   (catch (lambda (ex)
            (printf "Error: ~a" ex)))
   (finally 
    (if (> b -2) 
      (d a (sub1 b))))))

Вот расширение синтаксиса, которое сделало возможное выше:

;; try-catch-finally on top of with-handlers and dynamic-wind.

(define-syntax try
  (syntax-rules (catch finally)
    ((_ try-body ... (catch catch-proc))
     (with-handlers (((lambda (ex) #t)
              (lambda (ex) 
            (catch-proc ex))))
            (begin
              try-body ...)))
    ((_ try-body ... (catch catch-proc) (finally fin-body ...))
     (dynamic-wind
     (lambda () ())

     (lambda ()
       (with-handlers (((lambda (ex) #t)
                (lambda (ex) 
                  (catch-proc ex))))
              (begin
                try-body ...)))

     (lambda () fin-body ...)))
    ((_ try-body ... (finally fin-body ...))
     (dynamic-wind
     (lambda () ())

     (lambda () try-body ...)

     (lambda () fin-body ...)))))
6
22.10.2009 04:26:04
Это было не то, что я искал. В Схеме большинство функций автоматически проверяют деление на ноль и другие ошибки, как это происходит? Является ли отлов неявным во всех определениях?
unj2 21.10.2009 12:18:50