Pregunta

Estoy sorprendido por la función de "error" en PLTScheme. Si tengo una división por cero, es imposible hacer cualquier otra recursividad y apenas sale de la pila de llamadas y me da un error.

¿Hay una continuidad implícita antes de que todas las funciones? No tirar el error de distancia de la pila de llamadas? ¿Alguien tiene alguna idea sobre esto?

¿Fue útil?

Solución

En el Esquema PLT, el procedimiento de error plantea la excepción EXN: fallan , que contiene una cadena de error. No hay un "retén implícito" para todos los define. Mira el siguiente ejemplo:

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

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

Ejecutar la secuencia de comandos desde la línea de comandos y verá el intérprete existente después de imprimir algo así como

/: division by zero

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

Si una excepción no se maneja dentro del programa de usuario, se propaga hasta el intérprete núcleo donde un controlador predeterminado se ocupa de ella, es decir imprimir la excepción y salida. En otras palabras, el intérprete sólo dice, "una excepción fue levantado y no sabe cómo lidiar con ella, por lo que estoy Quiting". Esto no es muy diferente de la forma en la JVM o alguna otra máquina virtual manejar excepciones.

Para obtener más información sobre el mecanismo de manejo de excepciones de PLT Scheme, por favor leer sobre con-manipuladores y dinámica del viento en la MzScheme idioma manual. El uso de estos, incluso se puede emular try-catch-finally de Java bloque.

(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))))))

Aquí es la extensión sintaxis que hizo que lo anterior sea posible:

;; 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 ...)))))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top