There are a lot more things which might horrify you if only you knew .. :) Here's one that bit me: Felix optimises away unused variables. So if you do this:
proc f() { var x = { printn$ "Hello"; return 1; } (); } f(); you might expect from the eager evaluation rule that x will be set to 1 and "Hello" is printed, because f() is definitely called. Nacht! Nothing is printed! The code generated will (hopefully) be empty (a no-op). Why? Because you didn't USE the variable x. So it is optimised away, even thought that causes side effects from the RHS generator to be lost. This is deliberate and desirable. I did a lot of work slowing down the compiler optimisation a huge amount to enforce this because I was getting threads spawned and a server queue created because I failed to optimise away an unused variable; the async I/O system got loaded when it wasn't being used. if you want side effects, call a procedure. Generators can still be optimised away if their return values aren't used. here's another gotcha (this one is a bug): tail recursion. In a functional language you can replace tail calls with assignments to function parameters of the new arguments and a goto the top of the function (i.e. a loop). In Felix this transformation can be more than an optimisation, if the function has variables in it. Instead of spawning a new stack frame each recursion and initialising fresh copies of the variables, the tail-rec optimisation overwrites the variables with new values. Normally this doesn't matter, unless there is a pointer to a variable outside somewhere. In that case, the optimisation probably causes the pointer to point at the last value only, instead of the one it was set to point at (eg you might set the pointer on the first entry into the function). Felix tries to detect this kind of thing, and only apply the tail recursion to loop optimisation if it seems safe to do so. However I cannot prove the condition it checks is sufficient. It's very hard to know. Ideally all loops would be replaced by tail recursions, then optimised back to loops if possible (and not otherwise). This would actually solve the "problem" with closures referring to the "last" value a variable holds instead of the one it held when the closure was created (all the loop invocations would create a distinct stack frame so closures would bind to the frame that created them, instead of a single frame used for all iterations). Felix doesn't do this at the moment because it isn't clear the detector is good enough to ensure most loops will transform into tail recursions and back to loops, staying as recursions only when it would impact semantics. This is actually the proper solution to the semantics problem: get rid of all imperative data and control structures, define the semantics entirely as a functional system, and then optimise according to these semantics. Then we graft on loops into the concrete syntax and specify they're just sugar for recursions. I actually know (in principle) how to do this. It isn't easy! Instead I'm "trending" towards adding more and more functional constructions. For example instead of x . 1 = 2; // set a tuple component we use x = ( x with x.1 = 2 }; which rebuilds a completely new tuple and assigns that. This gets rid of the need to support assignment to components of tuples. Of course we can then *define* x . 1 = 2 as the above, so we get back to what we had, only now our semantics are largely functional. you can even get rid of variables with Continuation Passing Style. Every time you set a variable you actually invoke a new function. In general procedural code can always be transformed into functional code. In fact, Felix does the opposite internally: it tries to completely get rid of functions, but turning them into procedures :-) -- 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