I am currently working on an APL program for a class and have run into an issue with error handling.
In a function I made, I want to check to see that the input is an integer. If it is not, I want to return an error message and not run the rest of the function. So far, I compare to see if it's equal to the floor of itself. If not, I don't want the function to run and want it to stop. It works if I put 4.2
and gives an error message, but doesn't work if I put something like 'A'
in or 'ABCDEF'
and just gives a normal error. I tried making a try catch statement, but it gave me an error when it got to :Try
in my function.
Which isn't what I want. How can I make it so the function ends with an error message instead of continuing if the input is a character or string? I know I could put the entire code in an if block, but that seems really unnecessary.
My code in plain-text:
TESTER Q;error
:If Q≢⌊Q
'Possible'
:Else
'Not Possible'
:EndIf
'Again, Possible'
And as a screenshot:
If you want to explicitly quit early to avoid enclosing the entire code in a :If
block, you could do something like:
r←TESTER Q
:If 0≢⊃0⍴⊂Q ⍝ Q not a simple scalar number
:OrIf Q≢⌊Q ⍝ Q not an integer
r←'Not Possible'
→0
:EndIf
r←'Possible'
This works by using APL's prototypes:
⊂Q
makes sure to handle Q
as a whole.
0⍴
makes an empty list of that "type".
⊃
forces a prototypical element out, which is just like Q
but with all characters transformed to spaces and all numbers transformed to zeros. Now if Q
was a simple scalar number, the prototype is 0
, so we test for that.
Try it online!
However, it would be more proper for your function to reject the invalid argument by throwing a real error rather than returning or printing a result (which implicitly needs to be understood as an error) so that a function which calls yours can trap the error and take appropriate action. As follows:
r←TESTER Q
:If 0≢⊃0⍴⊂Q ⍝ Q not a simple scalar number
:OrIf Q≢⌊Q ⍝ Q not an integer
'Not Possible'⎕SIGNAL 11
:EndIf
r←'Possible'
Try it online!
⎕SIGNAL
throws an error optionally (the left argument) with a custom message, and the right argument is an error number from this list. Error number 11 is DOMAIN ERROR, which is the appropriate one in this case.
I understood that you tried using :Try
but got an error on that. Due to your tag and your screenshot, I can tell that you are using Dyalog APL, which where the syntax is:
:Trap 4 5 6 10 11 16
code to try goes here
:CaseList 4 5
handling of rank and length errors go here
:Case 6
handling of value errors goes here
:Else
all other trapped errors are handled here
:EndTrap
untrapped errors will throw as usual
Again, the error numbers used are those of the above linked list. (:Try
is a different error trapping system used in APLX.)