I'm trying to do some array documentation but it is getting
very painful. The problem is that the documentation basically
repeats and expands on what is in the library.

This means there's a maintenance effort involved keeping
the docs in sync with the library.

It's easier to explain how to read the library code.
So first some general ideas then that.

Felix is using type classes to describe some array properties.
The classes are in the file

        lib/std/array_class.flx

The most basic class is ArrayValue[t,v] where t is the element
type and v is the array type. ArrayValue is the concept of an array
as a value. It has two virtual functions:

        //$ Length. 
        virtual fun len: t -> size; 

        //$ Unchecked common indexing. 
        virtual fun unsafe_get: t * size -> v; 

Any type which wants to be considered as an ArrayValue simply
instantiates these functions, and it automatically gets all the
rest. These other derived methods are:

  //$ Checked common indexing.
  fun get[I in ints] (x:t, i:I)

  //$  Checked common indexing.
  fun apply [I in ints] (i:I, x:t) => get (x,i.size);

  //$ Callback based value iterator.
  proc iter (_f:v->void) (x:t) 

  //$ Callback based index and value iterator.
  //$ Callback f index value.
  proc iiter (_f:size -> v->void) (x:t) {

  //$ Stream  value iterator.
  gen iterator(xs:t) () : opt[v] = 

  //$ Traditional left fold.
  fun fold_left[u] (_f:u->v->u) (init:u) (x:t): u = {

  //$ Traditional right fold.
  fun fold_right[u] (_f:v->u->u) (x:t) (init:u): u = {

  //$ Membership by predicate.
  fun mem(pred:v->bool) (x:t): bool = {

  //$ Membership by relation to given value. 
  fun mem[u] (rel:v*u->bool) (x:t) (e:u): bool =>

  //$ Array as Set:
  //$ Membership by equality of value type.
  instance[with Eq[v]] Set[t,v] {
    fun \in (elt:v, a:t) => mem eq of (v * v) a elt;

  //$ Searching for value satisfying relation to given value.
  fun find (rel:v*v->bool) (x:t) (e:v): opt[v] = {

  //$ Searching for value satisfying predicate.
  fun find(pred:v->bool) (x:t): opt[v] = {

and more may be added.

The get(a,i) method is a checked version of the unsafe_get method.

The apply function is interesting. When you write:

        f a

where a has type A, and f has type A -> X, then f a is
a function application. But suppose we want


        assert 1 (1,2,3,4) == 2;

that is, we want to apply an integer to an array as an index,
which indeed we do want. When a value is syntactically applied
to another value, and the type of the value is NOT a function
type, Felix tries to find an function named apply with a tuple
argument consisting of the type of the applicator and the applicatee.
In this case it tries to find a function that matches the name and
signature

        apply: int * int ^ 4

This indeed matches the library function:

        fun apply [I in ints] (i:I, x:t) => get (x,i.size);

 where I in ints means "any integer type". So the application

        1 (1,2,3,4)

is replaced by

        get ( (1,2,3,4),  1)

and we have that integers can be used "as projection functions" for arrays.
And now we can write this too:

        (1,2,3,4) . 1

because Felix compiler has another piece of magic: when it sees:

        a . f

and "a" isn't a struct or record or pointer thereto, it consider the operator
to mean "reverse application" and replace it with

        f a

This is how Felix gets "OO like method calls" without any OO involved.

Next we have iter and iiter. These are your usual higher order functions
which take a callback procedure as an argument and call it for every
entry in the array. The iter function is called with each array value
in sequence, the iiter function also gets the index.

The iterator function is a stream generator.  For our sample array
it produces the infinite stream of values

        Some 1, Some 2, Some 3, Some 4, None, None, None .....

Generators work by assigning the generator to a variable and
then repeatedly calling it, like this:

        var g = iterator (1,2,3,4);
        var v1 = g(); // Some 1
        var v2 = g(); // Some 2
        ....

although usually its done in a loop. Here is how you do it in a loop:

        for v in g do println$ v; done

This loop sets v to the argument of the Some value the generator produces
until it gets a None, which signals the end of the stream.  Felix also allows 
you
to write it like this:

        for v in (1,2,3,4) do .. done

This works for any data type with a suitable method named "iterator".
[BTW: do NOT call your variables "iterator", its a special name due
to the above magic]

The two folds are traditional fold operations, called "accumulate" in C++.
However folds are purely functional. They accept a binary operator
such as "add" which is used to aggregate the array values.
Fold_left goes from left to right. Fold_right goes from right to left.

The first mem function test if the array contains a value that has
the given property (predicate). The second one accepts a comparison
and a value instead. The third one is the easiest to use and just
uses the standard equality operator for the type (but of course only
works if the type has a standard equality operator). You can also
use the infix operator \in for this method. That is a TeX symbol and
will be displayed as the usual "e" set membership operator by
the Felix webserver.

The two find functions are similar to the first two mem functions,
only they return the first value in the array that matches the predicate
as Some v, or None if there's no such value.

The following SHOULD be defined in the library but isn't:

        index

which find the index of a matching value instead of the value,
and 

        ifind

which returns both the index and value.


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




------------------------------------------------------------------------------
LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial
Remotely access PCs and mobile devices and provide instant support
Improve your efficiency, and focus on delivering more value-add services
Discover what IT Professionals Know. Rescue delivers
http://p.sf.net/sfu/logmein_12329d2d
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to