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