I have now committed some really cool Felix in the demos/embed directory which show how to use Felix inside a foreign event loop.
You will require SDL2, TTF, and freetype. You will have to configure them too. The make target "evtdemo" is setup for my OSX system so that too will need editing. I chose SDL because it's a good real example. I may set up an artificial one later. The demo is static linked. It uses async I/O and pthreads. Both work fine! It also uses the new function external_multi_swrite to allow the C++ code to write data to the Felix code. But just for fun, an old GOTCHA surfaced! Can you see why this code is an infinite loop hogging the processor? // Now process keyboard events sent from C++ spawn_fthread { var e = read kinp; while true do println$ "Got a KB event"; e = read kinp; done }; It just prints Got a KB event forever! Why? I was hunting through the driver code, confused because even with driver debugging on .. that sill code was not doing any channel I/O. This code works just fine: spawn_fthread { var e = read kinp; while true do println$ "Got a KB event"; C_hack::ignore(e); e = read kinp; done }; It's the old GOTCHA. Felix elides unused variables and their initialisers. The variable e containing the SDL event sent from C++ is not used so it is elided .. along with the channel read :-) Eliminating unused function results is sensible. Eliminating generators with side effects isn't. But Felix can't tell the difference. Actually for direct calls it can, but for closures it can't because generators have the same type as non-side effecting functions. generators are a hack, so you can do things like e = read chan, instead of using a procedure: var result: T; read (chan, &result); This is a trick to appease C lovers. Side effects in expressions defeat the whole idea of referential transparency. Anyhow, be aware of the issue. If you use a generator with side effects in an initialising expression and you want to preserve the side effects you MUST use the result of the calculation. The hackery is partly driven by the bad syntax used in block structured languages: var x:int; // uninitialised!! read (&x); // initialise by storing at the address Uninitialised variables HAVE to be allowed to make this work, and you have to actually use them. With generators: var x = read (); it's clearer the variable really is initialised, but that introduces the GOTCHA. Elimination of unused variables is mandatory, that is, it isn't only a necessary optimisation, Felix guarantees it. The reason is you should be able to do things like: var x = clock(); which requires async I/O to create a timer. But if you don't need it, it doesn't happen. in other words we specifically WANT to eliminate the side effect. This allows you to write code that sets up environments, but if you don't use it, the setup is removed. Another example: var default_database = sqlite3 (".felix/database.db"); If you want the database, its there. If you don't use it, it isn't :) -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Subversion Kills Productivity. Get off Subversion & Make the Move to Perforce. With Perforce, you get hassle-free workflows. Merge that actually works. Faster operations. Version large binaries. Built-in WAN optimization and the freedom to use Git, Perforce or both. Make the move to Perforce. http://pubads.g.doubleclick.net/gampad/clk?id=122218951&iu=/4140/ostg.clktrk _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language