2009-10-13 17 views
5

Jestem zaskoczony funkcją "błąd" w PLTScheme. Jeśli dzielę przez zero, to nie robi żadnej innej rekursji i po prostu wychodzi ze stosu wywołań i daje mi błąd.Jak błędy PLTScheme Catch?

Czy istnieje domniemana kontynuacja przed wszystkimi funkcjami? Czy błąd wyrzuca stos wywołań? Czy ktokolwiek ma jakieś pojęcie o tym?

Odpowiedz

6

Na schemacie PLT, błąd procedura podnosi wyjątek exn: nie, który zawiera ciąg błędu. Nie ma "ukrytego haczyka" dla wszystkich definicji. Spójrz na poniższym przykładzie:

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

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

Wykonać powyższy skrypt z linii poleceń i widać interpreter istniejący po wydrukowaniu coś podobnego

/: division by zero 

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

Jeśli wyjątek nie jest obsługiwana w programie użytkownika, jest on propagowany do interpretera podstawowego, z którym traktuje go domyślny program obsługi, tj. wypisuje wyjątek i kończy działanie. Innymi słowy, tłumacz po prostu mówi: "Wyjątek został podniesiony i nie wiem jak sobie z tym poradzić, więc rezygnuję". Nie różni się to znacznie od tego, w jaki sposób maszyna JVM lub inna maszyna wirtualna obsługuje wyjątki.

Aby dowiedzieć się więcej na temat mechanizmu obsługi wyjątków schemacie PLT, przeczytaj o z-ładowarki i dynamicznego wiatru w MzScheme Language Manual. Używając ich, możesz nawet emulować blok próbny catch-finally Javy.

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

Oto rozszerzenie składni, które sprawiły, że powyższe możliwe:

;; 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 ...))))) 
+0

To nie było to, czego szukałem. W Scheme, większość funkcji automatycznie sprawdza dzielenie przez zero i inne błędy, jak to się dzieje? Czy połów jest ukryty we wszystkich definicjach? – unj2

+0

@kunjaan Zaktualizowałem moją odpowiedź. –