Error Handling (13 of 14)
Errors in calculator mode
If you enter a statement containing an error in calculator mode, APL responds with an error message. For example, if you attempt an operation on unsuitable data, you normally get a domain error:
1 1 0 11 ∨ 1 1 0 0 DOMAIN ERROR 1 1 0 11 ∨ 1 1 0 0 ^
As the example shows, the statement containing the error is displayed with an error indicator (^) marking the point at which the APL interpreter thinks the error occurred.
To correct an error in calculator mode, simply retype the statement correctly, or use the line-editing facilities of your APL session to correct the line and re-enter it.
Errors in user-defined functions or operators
If an error is encountered during execution of a user-defined function or operator, execution stops at that point. The appropriate error message is displayed, followed on a separate line, by the name of the function containing the error, the line number at which execution stopped and the statement itself:
LENGTH ERROR C 1 2 - 1 2 3 ^
The above example shows that execution stopped in function C at line 2.
Many modern APL interpreters include a Debug window which you can use to examine and correct errors in a user-defined function.
The state indicator
It may be that the function at which execution halted was called by another function. You can use a system function called )SI, the State Indicator, (or, in some APLs, inspect a system variable called ⎕SI), to see the state of play:
)SI C * B A
This display tells you that function C was called from line 8 of function B which was itself called from line 5 of function A. (The exact format of the display may be different for your APL interpreter; the examples in this section are taken from APLX - no longer available).
The asterisk on the first line of this APLX example means that the function named on that line is suspended. The other functions are 'pendent'; their execution cannot be resumed till execution of function C is completed.
If at this point you executed another function, D, which called function E, and at line 3 of E a further error occurred, the state indicator would look like this:
E * D C * B A
Effectively it contains records of two separate sequences of events:
E * D ------------------- C * B A
You can clear the top level of the state indicator (i.e. the record of the most recent sequence) by entering the branch symbol → on its own:
→ )SI C * B A
In this example, another → would clear the remaining level (now the top level) and restore the state indicator to its original (empty) state.
Alternatively, you can clear the entire state indicator at any stage by using the system command )SICLEAR or )RESET or similar, depending on your APL.
Action after suspended execution
Apart from examining the state indicator, what can you do when execution is suspended?
If you want to resume execution at the point where it stopped you can do so by using the symbol → followed by the line number. If, for example, execution halted at line 3 of E, to resume at that point you could type:
The niladic system function ⎕LC returns a numeric vector of all current line numbers of functions in the State Indicator. The first number is that of the function at the top of the state indicator stack, so you could achieve the same effect by typing:
You don't have to continue from the point where execution was suspended. You can specify a line other than the current line:
Equally, you can specify execution of a different function.
What's perhaps most likely after an error in execution of a function is that you'll want to correct the function containing the error. You can usually edit the function and then resume execution by using →⎕LC. Alternatively some APLs include a Debug window where you can fix errors.
Error trapping and tracing
You can specify in advance what should happen if an error occurs during execution, in which case that error will not cause execution to stop. For example, if you wrote a function which invited the user to type in some numeric data, you might foresee the possibility that he or she would type non-numeric data instead. This would cause an error. APL allows you to 'trap' the error at runtime.
The details of error handling vary from one APL implementation to another, so you need to check which error handling method(s) your APL supports. An overview:
A block of code (including any functions called from within the block) can be executed under error-trapped conditions using :Trap..:EndTrap. If an error occurs, control passes to the :Case or :Else sections.
The system variable ⎕TRAP allows precise control what should happen where in case of an error.
- So-called error-guards allow error-trapping within Direct Functions, a specific enhancement of Dyalog APL.
⎕EA - Execute Alternate; executes the right argument. If that fails, the left argument is executed.
⎕EC - Execute Controlled; executes a statement and returns the result (if any) and additional information about any errors.
APL+Win supports the ⎕ELX system variable with a right argument which is executed whenever an error occurs.
- The :Try, :Catch, :Finally control structure can be used to protect a section of code.
NARS2000 offers the system variable ⎕ELX which takes any APL statement. This statement will be executed in case of an error.
Simple error trapping on a single line or expression can be achieved using ⎕EA, which allows an alternate line of code to be executed in the event of an error, or ⎕EC, which executes code under error trapped conditions and returns a series of result codes. These are compatible with IBM's APL2.