Here's an explanation I dreamed up that may make more sense.

When you write:

        val x = 1;

in Felix this is the same as

        #define x 1

in C, except it is typed. It's the name of an expression. In particular
if you write:

        var a = 1; var b = 2;
        val x = a + b;
        ++a;
        var c = x;

it's similar to C again:

        int a = 1; int b = 2;
        #define x a + b
        ++a;
        int c = x; // expands to a + b which == 4

When you write

        var a = 1;
        var b = 2;
        fun f (x:int) => x + b;

it's the same as in C except its typed properly:

        #define f(x) x + b

so 

        ++a; ++b;
        var y = f a;

is the same as

        int y = f a; // 2 + 3 which = 5

In Felix when you write:

        fun f(x:int) = {
                var y = x + 1;
                return y;
        }

the variable y is "qualified" on each expansion, unlike C,
so it isn't duplicated. Felix actually adds a unique counter
to the name to do this eg, x_123472 or something :)

And if you write

        fun f (var x : int) => x + b;

this is just short hand for

        fun f(x': int) = {
                var x = x';
                return x + b;
        }

Since var's are executed immediately and the var is at the top
of the function, this has the effect of "eager evaluation" instead
of the usual substitution (which is lazy evaluation).

So Felix vals and functions are really macros. If you're able to understand
C macros you can understand Felix vals and functions.

Well there's a little white lie here: sometimes Felix will use eager evaluation
anyhow.

Also there's some magic: you can use a macro as a proper function,
that is, you can create a function value or closure. For a C binding:

        fun f : int -> int = "$1+1";

always uses substitution so Felix actually generates a wrapper:

        fun wrapper (var x:int) : int => f x;

In C++ this is a class:

        class wrapper {
                int x;
        public:
                int apply (int x) { return f (x); }
        };

and a closure is just an object:

        wrapper closure = wrapper ();
        int y = closure.apply(x);

A function accepting a closure just takes a pointer to the class object.
Its actually a bit more tricky of course! It's really:

        class int_to_int { public:
                virtual int apply(int) = 0;
        };
        class wrapper : public int_to_int { ... }
        int_to_int *closure = new wrapper();

We do this, so the upcast to the public abstract base hides
the function and leaves only a pointer to the type. This means
a higher order function will work with any function of the required
type as an argument.

IN REALITY Felix also generates actual C functions, so there are
THREE distinct possible implementations: macro like, C function
like or C++ class like. Felix tries them in that order, because that's
the order of fastest performance. The evaluation rules are specifically
defined to allow this, that is, they just describe what the implementation
actually does.

The reason for this approach can be seen by examining Haskell or
Ocaml, where  the stricter semantics make it very hard to generate
performant code. Haskell requires the *compiler* to prove a function
is strict before using eager evaluation. Felix *assumes* the function
is strict by default, and provides a way to override this.  Consequently
Felix generates much faster code.

Performance matters in two cases in particular: inner loops,
and high level optimisations. It's particular important when the
value being manipulated are matrices or some other very large
structure where even a single operation saved has a significant
performance impact.

My belief is that most of the time it doesn't matter much so 
indeterminate evaluation is a good default.

It's also important to note that whilst the semantics of purely
functional code is reasonably well understood, NO ONE
has any idea about procedural programming. There isn't
any good theory for it, just lots of broken theories.
        

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




------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to