So here is an example. 

The FAIL function is very general and
will probably go in the library.

//////
gen FAIL[ret,exn] : exn -> any = "(throw $1,*(?1*)0)";
//////

Unfortunately, you have to give the type "ret" which is the
type of the C++ expression. Felix compiler actually knows this
type from context. However it doesn't know what to do with it
since FAIL is a just an ordinary library binding. The compiler
fools itself into believing the type is that determined by context,
but to get the C++ right you have to specify it anyhow.

Note the function return type is "any". This tells Felix that
the function never returns.


Now here is use in a function:

////////////////////
noinline fun fred (var x: int) = 
{
  var y = match x with
    | 1 => 2
    | _ => FAIL[int] "message" 
    endmatch
  ;
  return y;
}

proc check(x:int)
{
try
  var z = fred(x);
  println$ z;
catch a:string =>
  println$ "FAIL " + a;
endtry
}

check 1;
check 2;
////////////////// RESULT: ////////
2
FAIL message
////////////////////////

Please note the function "fred" is marked noinline.
This is essential in general (although in this case
it works inline or not).

Now a similar example, this time with a procedural
throw:


////////////////////////
noinline fun fred2 (var x: int) = 
{
  match x with
    | 1 => println "ONE";
    | _ => FAIL[void] "message";
    endmatch
  ;
  return "OK";
}

proc check2(x:int)
{
try
  var z = fred2(x);
  println$ z;
catch a:string =>
  println$ "FAIL " + a;
endtry
}

check2 1;
check2 2;
////////////////////////////////////RESULT
ONE
OK
FAIL message
/////////////////////////////

If you take out the "noinline" then in this case we get instead:

////////////////
ONE
OK
Exception type string : message
/////////////////

The last diagnostic is because the exception is catch in flx_run
in the try block surrounding the scheduler. That's because after
inlining the function fred2, we're probably throwing out of a 

        continuation -> resume()

method call invoked by the driver, rather than the try/catch block.
It's likely this kind of code will just crash in normal circumstances
because attempting to perform a service call or invoke a procedural
closure, or return, is all implemented by returning "this". The code
expects to be inside a "resume()" method, with no intervening
stack. [However C/C++ will do a return and clean up the stack,
which is why it works in some cases, even if the stack
isn't empty]

The effect of all this is:

the FAIL function is a fully general way of aborting in case of an error,
however such uses of C++ throw does NOT imply a try/catch will work
in all cases it would in C++.

--
john skaller
skal...@users.sourceforge.net
http://felix-lang.org




------------------------------------------------------------------------------
Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET
Get 100% visibility into your production application - at no cost.
Code-level diagnostics for performance bottlenecks with <2% overhead
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap1
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to