On Mon, 2007-09-10 at 15:27 -0700, Erick Tryzelaar wrote:

> Also, since do-done are already keywords, we could make them
> synonymous with braces in this situation, so that we could reduce the
> foreach to this, which is much easier to read:
> 
> d.foreach do |d:string|
>   println d;
> done;

I'm thinking to make begin/end keywords. Begin/end mark a block,
and are equivalent to { } sometimes, like Ocaml.
do/done marks a loop or control structure *without* a scope,
i.e. it's labels and gotos.

So vaguely:

        whilst c begin sts end;
==>     whilst c do { sts }; done;

> I'm just not sure how we handle errors, though.

What errors?

If you make a programming error, and Felix detects it,
Felix aborts. This is right IMHO. It's a bug. Fix it!
Felix has a Zero Tolerance policy for bugs.

So .. if you say 'open f' and f doesn't exist, Felix
aborts, as it should. Otherwise use

        let h = try_open f in match h with
        | Failed => ...
        | Handle h => ..
        endmatch


Felix does 'exceptions' with some messiness. In procedures,
use a non-local goto:

        proc f() {
                proc exc(){ goto err; }
                println "Stuff";
                g (the exc);
                return;
        err:>
                println "Error";
        }

        proc g(exc:1->0) {
                ...
                exc(); // throw exception
                throw exc; // throw exception

                val x = h exc 1;
        }

        fun h(exc:1->0) (x:int)= {
          if x<0 do throw exc; done;
          return x;
        }

You have to 'throw' an exception out of a function.
Throw really does use a C++ throw. Probably should make

        fun throw[t]: (1->0)->t = "(?1) (throw (con_t*)$1)";

The problem with 'throw' is that it doesn't unwind 
procedure stacks properly: it leaves the _caller variable
set, which means if there is a pointer to a variable in
the call chain, the chain is reachable and won't be collected.

Really, we should have call data= _caller + display including
pointer to data object, so unwinding the call data is always
safe, even if there is a pointer to some variable in the
stack frame .. however this would require TWO allocations.

BTW: _throw is a builtin primitive .. :)

Note that EH will be easier to do if we can ensure all 
functions throwing are converted to heaped procedures;
unfortunately it's hard to tell if a closure (func or
proc passed as a value) throws.. it would have to be
made part of the type.



-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to