Errors are anomalous or exceptional conditions which require special processing. So, exception handling is the process of responding to exceptional circumstances which occur during computation.
Why Use Exception Handling?
What other alternatives do we have if we do not use exception handling? We can use the if-else statement for error detection, reporting and handling. For example, suppose we have a method which reads an entire file into memory. This method does the following tasks in order:
However, we might encounter some problems in each tasks such as the file cannot be opened, not enough memory can be allocated, the file cannot be read and many more. Without handling these problems, the program will then crash. Hence, we program the code such that it does error detection and handles all these errors. One way in doing this is as follows:
Suppose we have the following words:
FALSEif the file cannot be opened, otherwise returns
FALSEif the size cannot be determined, otherwise returns
FALSEif the there is not enough memory to allocate, otherwise returns
- And more words to complete the checks
: try-open-file file? not -> -1 | size? not -> -2 | allocate? not -> -3 | ... ... otherwise 0 |. ;
As you can see, there are much testing to be done, and it would be likely to miss some of the checks, causing the program to crash. For cases with even more errors that need to be detected, we might get lost in it. It would also be hard to find bugs in the code.
There is another disadvantage if we do not have exception handling. Suppose that the method above is within a series of nested methods. In other words, consider a case where we run a method called function1, which calls another method named function2, which calls the above method to read a file. We will then need to pass the error from the reading file method into function2 and then function1. All the functions involved will need to check for errors, even for those functions that are not interested in detecting errors. For a program with long nested methods, there would be a huge error bubbles.Using exception handling will help solve these two main problems, which helps simplify our code. Instead of having to write all the if-else statement and bubble errors up the series of functions, we can just use the
CATCHmechanism. If the program catches an exception, it will just abort the task which throws the exception and return to the state before the current task has been conducted. In Smojo, we can see that in the case of an error, the depth of the stack remains the same.
Smojo provides a number of words for exception handling. The Stack Changes are conditions of the stack before and after while z*x means z items are on the stack.
|Takes one argument, the error number. This word halts the further execution of a word, and puts execution at the point
CATCHwas last called.
Stack Changes: ( n = error number ) k*x n -- k*x n
|Takes an XT and runs it. If somewhere in it, the system
THROWs an exception, the XTs execution is halted and the
THROW's error number is placed on the stack. In the case of an error, the depth of the stack is left unchanged.
Stack Changes: ( 0 = no error , n = error number ) i*x xt -- j*x 0 | i*x n
|Executes the given XT and signals an error if thrown (
TRUEif there is an error and
FALSEotherwise). Two kinds of errors are caught:
THROWmechanism is signalled using the error number -2.
Stack Change: ( n = -3 for java error, n = -2 for
THROWgenerated exception) i*x xt -- j*x false | k*x error n true | l*x n true
|Unconditionally sets the runtime's exception flag and creates a multi-level exit.|
: negative? dup 0 < if 100 throw else 1 + then ; 10 ' negative? catch .s <2> 11 0 ok -10 ' negative? catch .s <2> -10 100 okExample 2
: problem "problem" . 1 throw "but you'll never see it again." . ; : rocket "houston we have a" . problem "time to abort" . ; : launch ['] rocket catch 0 = -> cr "Success!" . | otherwise cr "Fail!" . |. ; launch houston we have a problem Fail! okExample 3
1 :> 1 + + ; try .s <3> java.lang.ArrayIndexOutOfBoundsException -3 true ok
Explain the logical flow of the program in Example 2.
catchof the nested call, which is
['] rocket catchin
launch. Since an error occurs, an error number ( not equal to 0 ) is put on the stack, thus "Fail!" is printed following the conditionals.
Question 2Write a word
/0?that takes two numbers as arguments. It throws an error if the second number is zero. Otherwise, divide the two numbers as usual.
: /0? dup 0 = if -1 throw else /. then ;