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