Вопрос

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

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

Это было полезно?

Решение

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

;; 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 Scheme, прочтите с обработчиками и динамический ветер в Руководство по языку 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 ...)))))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top