7. Control structures¶
7.1. Structured programming¶
Languages in early days such as Fortran and COBOL use goto
statement extensively, which results in obscure program structure. In
1968, Dijkstra insisted a program structure is more readable if it is
a hierarchical composition of sequences, iterations and conditional
branches.
Loop in early Basic and Pascal
10 X=1
20 IF X>=1000 THEN GOTO 60
30 PRINT X
40 X=X*2
50 GOTO 20
60 END
x = 1;
while x<1000 do
begin
writeln(x);
x = x*2
end;
7.2. Non-local exits¶
According to the idea of structured programming, it is not a good code
to jump over block structures, but we sometimes want to write such
code. For example, a return
statement immediately exits from the
function block even if it is in nested blocks.
Non-local exits is an enhanced version of return
(and tamed
version of goto
) that terminates nested function calls at once and
goes back to the outer level function.
Catch and throw in Ruby
def bar
throw :a, 3
end
def foo
bar
end
catch(:a) do
foo
end
7.3. Exceptions¶
7.3.1. What is exception?¶
In early languages, if something unusual occurs during execution, the program has no choice but to stop with an error message. Recent languages can deal with such situation more gracefully.
An exception is an unusual event in a program for which we need some extra processing.
Detected by hardware: division by zero, to read or write protected memory, end of file, etc.
Detected by software: index of an array is out of range, etc.
Defined by programmers: anything you wish.
7.3.2. Exception handling¶
Even if a language has no exception handling mechanism, it is possible to write a program that deal with unusual events. However, exception handling is more convenient in the following way:
No need to write codes for detecting exceptions. Imagine if you need to check that the divisor is not equal to 0 before every division.
Cleaner code for dealing with an unusual event, especially when it requires non-local exits.
Managing several exceptions in one place.
An exception handler is a part of program that is invoked when an exception occurs.
Exception handling in PL/I
An exception handler can be written in anywhere in the program with
the ON
statement. For example, the following is a handler for an
exception SUBSCRIPTRANGE
, which occurs when an index of an array
is out of range.
ON SUBSCRIPTRANGE
BEGIN;
PUT LIST ('ERROR') SKIP;
END;
Note that the ON
statement is an executable statement (not a
declaration), which means bindings between exceptions and exception
handlers are dynamic. An exception handler is valid after an
ON
statement is executed, and until another ON
statement
with the same exception name is executed.
In addition, in order to make an execption handler valid, we need
to write an exception name before a part of the program in which
the exception may occur. For example, the following code checks
the index I
if it is out of range or not.
(SUBSCRIPTRANGE):
BEGIN;
A = B(I);
END;
Exception handling in Java
An exception is represented by an instance of an exception class, which is passed to a handler as an argument.
Exception classes are hierarchical. An execption handler can deal with many kinds of exceptions by specifying a high level exception class in the hierarchy.
Bindings between exceptions and exception handlers are lexical.
try-catch-finally
statement makes the scope of handlers.try { FileWriter x = new FileWriter("sample.txt"); // IOException may occur } catch (IOException e) { e.printStackTrace(); }
By declaring
throws
at the head of a method, an exception can be propagated to the calling method, which allows dynamic bindings between exceptions and exception handlers.static void bar() { try { foo(); } catch (IOException e) { e.printStackTrace(); } } static void foo() throws IOException { FileWriter x = new FileWriter("sample.txt"); }
If there is a possibility of an exception, programmers must either write an exception handlers or propagate it. The aim of this rule is to make programs robust in unexpected situations.
Excercise 15
Java forces programmers to handle exceptions, but that is not the
case for Error
and RunTimeException
. Guess the reason.