Just for fun I made this work:

//////////////
#import <flx.flxh>

proc A () 
{
  var x = 2;
  while (x>0) {
    println$ "Hix-"+x.str;
    for (int y = 4; y>0; --y) 
    {
      if (y == 2) break;
      println$ "Hiy-"+y.str;
      continue;
      println "Never";
    };
    --x;
  };
}

A;
/////////////

Note the 'int y = 4' localises y inside the for loop.
Also note the 'y.str' which means 'str y': but this would
work too:

        println y.str;

whereas this does not:

        println str y; // need a $

because . binds more tightly than application.

break and continue ONLY WORK IN C LOOPS.
They do NOT work in Felix loops (because Felix loops 
are not blocks). In the for loop, you can ALSO say 'redo'.
This goes back to the test condition WITHOUT executing
the iterator.

Finally .. return does NOT work because a block is a lambda
function. More precisely, you actually can say 'return' and
it will return from the invisible block containing it.

This could be fixed, by changing the Felix return keyword to 'ret'.
Then return would just jump to 'return_label' which is put
at the end of every user defined procedure (but not anonymous ones).

This will never work for functions, which instead would use
something like:

        try { ...
                throw result; // ret result
        } 
        catch (result_t result) { return result; }

however this is very expensive (and won't work 
reliably as written anyhow).

**************************************************8
BTW: Felix functions could be changed to be procedures.
instead of 'apply()' returning a value, it is a void
method which stores its value at pointer.

Already, generators are unravelled from

        f (g x)

to

        tmp = g x;
        f tmp

however, despite the fact they're stored in variables
and do the 'switch pc' at the start, they still actually
return values.

The point is that in the void form, our functions would
be allowed to read channels and issue service calls.
Oh, and this would include calling the gc.. if this were
done univerally, the gc could be called automatically,
including in the middle of functional code.

The unravelled form is eager evaluation, and can often
be slow compared to lazy evaluation (substitution).

In particular, the C primitives do lazy evaluation
at present:

        fun add: int * int -> int = "$1+$2";

literally replaces $1, $2 with argument expressions.
Even when unravelled, the unravelled assignments
can be put in a C block:

        { 
                t1 tmp1 = f1(a1); 
                t2 tmp2 = f2(a2); 
                result = g(tmp1, tmp2); 
        }

to save space in the object: the tmps go on the stack, and
they're local to the unravelled expresssion so if you have
several of them excess stack space isn't wasted. gcc may even
be more likely to use machine registers.

There are several options here...

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

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to