Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a try-catch block in scheme?

I'm trying to implement a try-catch block in scheme using (call-cc) method but i'm not sure how it can be used for that. I could not find any example.

And found examples contains just error-handling but what i want to do is: if an error occurred, the scheme program has to give a message to user (via display for-example) without suspending the program.

Is that possible?

like image 624
Asqan Avatar asked May 11 '13 02:05

Asqan


People also ask

How do you implement a try catch?

The “try… It works like this: First, the code in try {...} is executed. If there were no errors, then catch (err) is ignored: the execution reaches the end of try and goes on, skipping catch . If an error occurs, then the try execution is stopped, and control flows to the beginning of catch (err) .

What do you put in a try catch block?

Place any code statements that might raise or throw an exception in a try block, and place statements used to handle the exception or exceptions in one or more catch blocks below the try block. Each catch block includes the exception type and can contain additional statements needed to handle that exception type.

How do you implement a try catch in PowerShell?

Use the try block to define a section of a script in which you want PowerShell to monitor for errors. When an error occurs within the try block, the error is first saved to the $Error automatic variable. PowerShell then searches for a catch block to handle the error.

How is try catch implemented Java?

In Java, a try block installs itself into a special table (in the class file). When the JVM throws an exception, it looks at that table to see where the next catch or finally block to go to is.


2 Answers

Typically you'd use the with-handlers form. This lets you display an error message or take any other action before returning a value.

#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

If you really want to use a continuation directly for some reason, you could use call/ec for an error/escape continuation instead of the general call/cc.

Docs:

  • with-handlers

  • call/ec

like image 133
Greg Hendershott Avatar answered Oct 26 '22 20:10

Greg Hendershott


Since you want to catch all errors, such as ones raised by both raise and raise-continuable you'd need both an exception handler (to deal with raised conditions) and an exit continuation (to avoid continuing with the try body). Simple syntax for try would be:

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

This gets used as, for example:

> (try (begin (display "one\n")
              (raise 'some-error)
              (display "two\n"))
    (catch (display "error\n")))
one
error
some-error       # the return value.

Note: this is R6RS (and R7RS) Scheme.

like image 43
GoZoner Avatar answered Oct 26 '22 21:10

GoZoner