Как реализовать блок try-catch в схеме?
Я пытаюсь реализовать блок try-catch в схеме с использованием метода (call-cc), но я не уверен, как его можно использовать для этого. Я не мог найти никакого примера.
и найденные примеры содержат только обработку ошибок, но то, что я хочу сделать: если произошла ошибка, программа Схемы должна дать сообщение пользователю (через дисплей, например) без приостановки программы.
Это возможно?
2 ответов
так как вы хотите, чтобы поймать все ошибки, такие как те, которые поднимают raise
и raise-continuable
вам понадобится как обработчик исключений (для решения поднятых условий), так и продолжение выхода (чтобы избежать продолжения с try
тело). Простой синтаксис для try
будет:
(import (rnrs base) ; define-syntax
(rnrs exceptions)) ; get `with-exception-handler`
(define-syntax try
(syntax-rules (catch)
((_ body (catch catcher))
(call-with-current-continuation
(lambda (exit)
(with-exception-handler
(lambda (condition)
catcher
(exit condition))
(lambda () body)))))))
это используется как, например:
> (try (begin (display "one\n")
(raise 'some-error)
(display "two\n"))
(catch (display "error\n")))
one
error
some-error # the return value.
Примечание: это R6RS (и R7RS) схема.
обычно вы используете with-handlers
форма. Это позволяет отобразить сообщение об ошибке или выполнить любое другое действие перед возвращением значения.
#lang racket
(define (foo x)
(with-handlers ([exn:fail? (lambda (exn)
(displayln (exn-message exn))
#f)])
(/ 1 x)))
(foo 1)
; 1
(foo 0)
; "/: division by zero"
; #f
если вы действительно хотите использовать продолжение напрямую по какой-то причине, вы можете использовать call/ec
для продолжения ошибки / escape вместо общего call/cc
.
Docs: