The iterator feature of Felix is one of the things I find I'm using  lot!

Let's review it: here's a list iterator:

  gen iterator[T] (var xs:list[T]) () : opt[T] = {
    while true do
      match xs with
      | Cons (?h,?t) => xs = t; yield Some h;
      | Empty => return None[T];
      endmatch;
    done
  }

Combined with some parser magic we get

for elt in list(1,2,3) do .. done

Of course this is similar to

iter (fun (elt:int) = { ... }) (list(1,2,3));

but prettier, more imperative, and easily escapable,
but both bodies are callbacks (driven by the iteration).

Iterators are easy to combine in a function (call one, do
a calculation, and yield something, to make a new iterator 
from an old one).

Now here's another construction:

  ctor list[T] (f: (1->opt[T])) : list[T] = {
    var ff = f;
    fun aux (l:list[T]) = {
      var x = ff();
      return 
        match x with 
       | Some ?elt => aux (Cons (elt,l)) 
       | None => rev l
       endmatch
      ;
    }
    return aux Empty[T];
  }

This takes an iterator, and make a list. So given ANY data structure
with an iterator IT, and ANY data structure D with a comprehenive constructor,
we can write

        D IT

to make a new D. Notice that like STL iterators, the comprehension is 
independent
of the source data structure : the iterator IT abstracts it away. So crudely:

        var x = list (..);
        var y = list ( x.iterator );

So for any set of data structures Ds for which each D in Ds has a comprension
and an iterator, for any two data structures D1, D2 we can make D1 out of a D1
by a standard formula.

What does this mean? Well it means we can throw out all the constructors
that take one data structure to produce another if we want to. For example .. 
hehe ..

        list (1,2,3) ...

uses a list constructor taking an array argument but we don't need it, instead:

        list ( (1,2,3).iterator)

will do. Of course that's a clumsy notation .. 

        var x = list <<-- (1,2,3)       

?? [Unix pipe would be interesting except it's overused already for match cases]

What's even more interesting is that synchronous channels are closely related
to all this.

Another interesting thing .. if that's an iterator/iter .. what's a fold?

Well actually .. a constructor for

        typedef sum = int;
        ctor sum (f: 1 -> opt[int] ) = {
                var s = 0;
                for x in f do s = s + x; done
                return s;
        }

var y = list (1,2,3,4);
var s = sum (y.iterator);
println$ s;

and this constructor is a comprehension for an integer
(that adds up all the integers in a stream). [It works lol!]

So does this:

var y2 = 1,2,3,4;
s = sum (y2.iterator);
println$ s;


Pretty nice, our "sum" can add up all the values of ANY data structure!


STL can do that too, rigtht?

WRONG. STL only PRETENDS to do it.
You must understand templates are syntax macros.

A vector iterator and a list iterator in STL have the same
syntactic operations on them (deref, advance), but they
have different types.

Felix iterator have a type:

        1 -> opt[T]

All of them. In Felix an iterator is polymorphic in 
the value type and **independent** of the container type.

BTW: producer and consumers above (iterator and comprehension)
are coroutines.

OK .. so .. we really need a nice notation!

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




------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to