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

Reply via email to