Pergunta

Fico impressionado com a função "Erro" no PLTSCHEME. Se eu tiver uma divisão por zero, ela não faz nenhuma outra recursão e sai da pilha de chamadas e me dá um erro.

Existe uma continuação implícita antes de todas as funções? O erro joga fora a pilha de chamadas? Alguém tem alguma idéia sobre isso?

Foi útil?

Solução

No esquema PLT, o procedimento erro levanta a exceção EXN: FAIL, que contém uma string de erro. Não há "captura implícita" para todos os define. Veja a seguinte amostra:

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

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

Execute o script acima da linha de comando e você verá o intérprete existente depois de imprimir algo como

/: division by zero

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

Se uma exceção não for tratada no programa de usuário, ele será propagado até o intérprete principal, onde um manipulador padrão lida com ele, ou seja, imprima a exceção e a saída. Em outras palavras, o intérprete apenas diz: "Uma exceção foi levantada e eu não sei como lidar com isso, então estou dizendo". Isso não é muito diferente de como a JVM ou outras exceções da manipulação da máquina virtual.

Para saber mais sobre o mecanismo de manuseio de exceção do esquema PLT, leia sobre com os mão-de-obra e Wind Dinâmico no Manual de idiomas mzscheme. Usando isso, você pode até emular o bloqueio de Java-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))))))

Aqui está a extensão de sintaxe que tornou possível o acima:

;; 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top