Felix currently allows certain non-functions to be used "as functions".

For example:

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

is a primitive function like thing, but it is NOT a Felix function which

        fun g (x:int) => x;

actually is. When you apply these entities:

        println$ f 1, g 1;

this involves terms:

        apply (f, 1)
        apply (g, 1)

and the compiler knows that f and g are different applicable things
and uses the appropriate code to apply them: for f we get

        1

by substitution and for g we get

        g->apply(1)

[although inlining me simplify that]. No consider the function

        fun eval (h: int -> int, x:int) => h x;

which accepts a function int->int as an argument. This function
will work fine with g, eval calls

        h->apply (x)

but it cannot work with f, because f isn't a function. So in these circumstances
we need to do something called eta-expansion aka generate a wrapper:

        fun f' (x:int) => f x;

and now we can pass f' to eval, because f' is a real Felix function.

This wrapper generation is done "automatically" for primitives
when a primitive is passed as a function argument or returned
as a function value. In fact it can even be done for an application,
it will still work, although it would be slow, unless the function
is inlined (in which case we get back to a primitive application).

However, primitives aren't the only things that need wrapping:
Felix has a few things that "act like functions in that they can
be applied but aren't functions". These include:

        non-const union constructors
        injections
        projections
        array projections
        C function pointers
        structs (as constructors can be applied to tuples)
        cstructs (as above)


Ok, so the rule seems simple: if you see

        apply (f,x)

then if x is a function like object that isn't a function,
generate a wrapper and pass that instead. For example you'd
expect this to work:

        fun add : int * int -> int = "$1+$2";
        var sum = fold_left add of (int * int) 0 (list(1,2,3));

We don't wrap the f in apply(f,x). 

Seems simple. Only it isn't ;(

First, there are a HUGE number of places where we might have a function
closure other than the second argument of apply. The argument of ANYTHING
for example :)

Such as: a tuple constructor, record constructor, union non-const constructor.
Just about ANY expression or statement has slots of some type T which allows
any type to be used, including a function type.

It gets worse! If a function is polymorphic then a Felix function and C 
function pointer
are not only different, leading to distinct specialisations, but terms like a 
non-const
union constructor do not even have kind TYPE.

The point is that when the types are fixed, we might say if the accepting type 
is

        D -> C

and the argument can be wrapped (cast) to such a type, go ahead. But certainly
for a C function pointer the type

        D --> C 

can be wrapped (note: the symbol --> with two dashes is for a C function rather
than a Felix one).

however the problem is given

        apply (f,x)

the first argument f might be an expression so we HAVE to recursively analyse 
that.
So it isn't clear exactly how to avoid wrapping f in just the special cases 
above.

The existing wrapping code has a bug: if you write

        x.1 = 5

to assign to a compact linear type second component wrapping the projection
there means the application isn't an lvalue and the assignment fails: it's 
essential
the projection isn't wrapped. the existing code wraps it and relies on the 
inliner
to "unwrap" it :) This requires a second inlining pass which is now eliminated
so now some test cases fail.

I just don't know how to fix it. I can't get the algorithm to make sense :)


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




------------------------------------------------------------------------------
Comprehensive Server Monitoring with Site24x7.
Monitor 10 servers for $9/Month.
Get alerted through email, SMS, voice calls or mobile push notifications.
Take corrective actions from your mobile device.
http://pubads.g.doubleclick.net/gampad/clk?id=154624111&iu=/4140/ostg.clktrk
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to