******************** Control structures ******************** ======================== 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. .. admonition:: Loop in early Basic and Pascal .. code-block:: basic 10 X=1 20 IF X>=1000 THEN GOTO 60 30 PRINT X 40 X=X*2 50 GOTO 20 60 END .. code-block:: pascal x = 1; while x<1000 do begin writeln(x); x = x*2 end; ================= 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. .. admonition:: Catch and throw in Ruby .. code-block:: ruby def bar throw :a, 3 end def foo bar end catch(:a) do foo end ============ Exceptions ============ .. index:: single: exception 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. .. index:: single: exception handler 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. .. admonition:: 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. .. code-block:: none 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. .. code-block:: none (SUBSCRIPTRANGE): BEGIN; A = B(I); END; .. admonition:: 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. .. code-block:: java 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. .. code-block:: java 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. .. admonition:: Excercise 15 :class: exercise Java forces programmers to handle exceptions, but that is not the case for ``Error`` and ``RunTimeException``. Guess the reason. :ref:`[Answer] `