method HELLO: Everybody's favorite program. PRINT "Hello world!" return
Note that the Gilda language is not case sensitive and the examples were formatted using a pretty printer.
> gilda -program hello :Compile the program. gilda: Building hello with debugging. gilda: hello.g --> obj/hello.o > hello :Run the program. Hello world!
Gilda includes a novel exception handling mechanism to help programmers write more reliable programs. In the Hello program an exception could occur if the standard output stream is broken. The method raises an exception and a last chance exception handler in the run time system attempts to print a message to the standard error stream containing a context string and a descriptive message.
Flush) Could not write to a stream.
Since the standard error and output streams are often the same the program would likely raise another exception. In this case the last chance handler in the run time system does not contain an exception handler and just quietly terminates. If instead you want to handle the exception, the simplest way is to add a coarse grain exception handler. The example handler attempts to beep when it catches an exception. Note that the handler method is coded in the same file as the primary method.
method HELLO: An example program with an exception handler. PRINT "Hello world!"; Printing can raise an exception. return catch: Catch any exceptions raised in the method body. WARNING_BELL; Standard library method to make a jazz noise. return
The library method, WARNING_BELL, needs to be imported; which is done inside a class. Class files declare the usual items like user types, static variables and member methods, but also declare build dependencies so that Gilda programs know how to build themselves.
class Hello: A class file for the Standard hello example program. import Gilda.Foundation :Access standard platform specific utilities. gilda Hello START :Declare the Hello method as the main entry point. return :A class Return simply designates the end of the file.
Nontrivial programs contain classes and are compiled by designating the top level class in the class hierarchy. To rebuild an entire program the Clean switch is used. Otherwise the compiler performs an incremental build. Keywords can be abbreviated to single letters for convenience.
Importing the Gilda foundation library causes platform specific methods to be imprted. The last line in the compiler output uses an intermediate generated assembler file named cm_run_catch.s which is translated into an object module containing exception information.
> gilda -c -p hello :Compile the program. gilda: Building hello with debugging. import: c:/program files/techneon/foundation/gilda.foundation.public.clg import: c:/program files/techneon/foundation/platform/os.platform.w32.clg import: c:/program files/techneon/foundation/platform/windows/platform.clg import: c:/program files/techneon/foundation/platform/windows/attribute.clg gilda: hello.g --> obj/hello.o asm: asm/gilda_run$catch.s --> obj/catch.o
Now when the program runs it will either print, beep, do nothing (if the beeper is disabled), or it could raise another exception. The latter case occurs when the program is run in a terminal emulator and the WARNING_BELL method is implemented by writing a control-G to the console via the standard error stream. In this situation the exception raised in WARNING_BELL is nested in an exception handler.
The run time system detects nested exceptions to avoid run away circular exceptions. If the programmer wants to permit nested exceptions the Retry attribute can be added to the "method catch" line. This is useful when writing handlers that want to retry an operation several times before giving up. When no Retry attribute is coded then a Retry fault exception is raised.
Fault exceptions are raised when a program has run amok and is usually indicative of a bug. They can also be raised by an Assertion statement; which is useful when debugging and supports the Contract Programming methodology [Meyer]. Methods can exit normally at a Return statement or they can exit by raising an exception or a fault.
Faults are treated distinctly from normal exceptions in Gilda programs. After a fault a typical strategy is to contain damage and retreat to a higher level or gracefully terminate. The context of a fault is less reliable due to potential corruption and correspondingly language support for faults is simpler and more coarse. The next example shows how we could catch the fault and quietly terminate.
In the hello.clg class file, import the Assertion.Call class for assertion support. Also add a dependency to build the First_Handler method; which will override the default version in the run time liibrary.
class Hello: A class file for the hello program with assertion support. import Gilda.Foundation, &Access standard platform specific utilities. Assertion.Call :Build with assertion support. gilda Hello START :Declare the Hello method as the main entry point. => First_Handler :Compile the First_Handler method in Assertion.Call. end
Now edit the hello.g method as shown below. We added a trace command to print details about the assertion. Traces are used to debug programs. The '`on' switch enables the trace; otherwise it would be ignored.
method HELLO: An example program with exception and fault handlers. use Assertion :Access the Assertion variable in the Assertion class. PRINT "Hello world!"; Printing can potentially raise an exception. return catch fault: Catch any faults that arise. trace`on Assertion; Trace the assertion contents for a program fault. return; Quietly exit. catch: Catch any exceptions raised in the method body. trace`on Assertion; Trace the assertion contents for a managed exception. WARNING_BELL; Standard library method to make a jazz noise. return
You can test the handlers by coding assertions in the Hello method.
We could still run into a problem with this program when it is run and there is no memory left. In this scenario after the program launches it attempts to enter the Hello method, but when it tries to allocate a stack frame it runs out of memory. The run time system detects this and raises a Stack Overflow fault to the last chance handler. It would either print a diagnostic message or failing that quietly terminate. If you wanted to explicitly manage the fault you could write a handler to override the default last chance handler.
The key observation is that unanticipated exceptions can occur in seemingly correct code. Gilda`s exception mechanism lets programmers manage both anticipated and unanticipated situations as they see fit. You can implement a simple exception handling strategy with little overhead. A more sophisticated strategy can be coded with little impact on the principle business logic.
This example illustrates general concepts for exception handling in Gilda. Exceptions are managed separately from faults. Handlers can be incrementally added without perturbing code in the body of the primary method. Contrast this with try-throw-catch; which would implement similar behavior by wrapping the Print statement in a Try clause and embed a handler within it as well [Malayeri]. Gilda lets you write well behaved programs that thoroughly check exceptions without becoming cluttered. You can incrementally add new handlers to existing programs; which is a natural way for programmers work.
Also notice that exceptions are not named. Named exceptions are not necessary for precise exception handling and when used names need to be carefully managed. Anonymous exceptions are not only less hassle to code, but also avoid problems with name conflicts and inappropriately overloaded names [Miller].
What this example does not illustrate is how exceptions are managed with more precision. It only hints at how context is propagated and does not show how user defined exceptions are specified. If you are curious then the easiest way to learn more is to get the Gilda compiler and start coding.
1. Bertrand Meyer. "Applying Design by Contract". IEEE Computer, pages 40-51, October 1992.
2. Donna Malayeri and Jonathan Aldrich. "Practical Exception Specifications", volume 4119/2006, pages 200-220. Springer Berlin / Heidelberg, October 2006. ISBN 978-3-540-37443-5.
3. Robert Miller and Anand Tripathi. "Issues with Exception Handling in Object-Oriented Systems". In European Conference on Object-Oriented Programming (ECOOP), volume 1241, pages 85-103, September 1997.