Question: how to define proc that returns expression sequence of two integers OR FAIL?

I want to make proc that returns expression sequence of two numbers, say. A,B

This will be the normal return, but if the proc encounters an error, it should return FAIL. But this is not possible, because if I type A,B:=foo(0) and foo() happenes to return FAIL then Maple will complain

Error, mismatched multiple assignment of 2 variables on the left side and 1 value on the right side

The three workarounds I see are these

Method 1

I could wrap foo() with try/catch and have foo throw an exception when it encouters an error instead of returning FAIL, but I do not like this. This will look like

restart;
interface(warnlevel=4);
kernelopts('assertlevel'=2):
foo:=proc(n::integer)::integer,integer;
  if n=0 then
     error ("encountered error");
  else
     return 1,2;
  fi;
end proc;

And now the caller will do

try
   A,B:=foo(0);
catch:
   print("encountered error");
end try;

method 2

Another option is to have foo() return ONE value back. In the case of an error it will be FAIL, and in the case of normal behavior, it will be a LIST of the two items, which then I have to extract.  Like this

interface(warnlevel=4);
kernelopts('assertlevel'=2):
foo:=proc(n::integer)::Or(list(integer),identical(FAIL));
      if n=0 then
         return FAIL;
      else
         return [1,2];
      fi;
end proc;

And now the caller will do this

L:=foo(1);
if L<>FAIL then
   A:=L[1];
   B:=L[2];
else
   print("failed call");
fi;

But this is not as easy as just calling foo() as   A,B:=foo() but I can't do this due to the mismatch problem.

Another method, commonly used in C programming is to have the function return status an additional output and this will indicate if the call was success or not. so the caller has to remember to always check for this before using the returned values. These are handled by errno, perror(), strerror(). But for now, lets make the function return the status.

So caller will first check if status is success first and if so, then it will read the actual returned values that follow it. Like this (status is true/false)

method 3

interface(warnlevel=4);
kernelopts('assertlevel'=2):
foo:=proc(n::integer)::truefalse,integer,integer;
  if n=0 then
     return false,0,0;
  else
     return true,1,2;
  fi;
end proc;

And the caller will do

status,A,B:=foo(1);
if status then
   print("call was success, A and B are ",A,B);
else
   print("call failed");
fi;

So the return values will always have status as first argument that the caller has to check before reading the rest of returned values.

From the above three options which you think is best?

Anyone can suggest alternatives to the above methods?

Please Wait...