One of the most common questions I get about coding in Fennel is about how to effectively use coroutines. Fennel runs on the Lua runtime, and Lua is famous for having very few features, but having carefully selected just the right features to include, and coroutines are one of those features that give a remarkable bang for their buck. But because most languages don't have them, they're often seen as an advanced or confusing feature. Once you get a grasp on them, they provide a great deal of flexibility and in many cases mitigate the problem of not having true concurrency1 on the Lua runtime.

fengari logo

I've found coroutines to be very helpful in a number of situations. I used them in Bussard for simulating space station operating systems which you could SSH into2 as well as for the tutorial system in EXO_encounter 667. But the most unusual use was for the interactive in-browser REPL on

So typically when you have a web site demonstrating a language, you need a server somewhere to run the code, and the site sends the code on to be evaluated there, hopefully in some kind of sandboxed context to avoid allowing users to take over control. The repl on Fennel's web page uses Fengari, which is a literal port of the Lua virtual machine to JavaScript, allowing Lua code to run in the browser exactly like it would normally. One big advantage of this approach (rather than compiling the Lua code into JavaScript) is that the browser runtime doesn't have coroutine support, but the Lua VM inside the browser does!

Now you probably know that REPL stands for Read, Eval, Print Loop. This is typically implemented using standard in and standard out in a terminal with something like this:

(fn loop []
  (let [input (
        value (eval input)]
    (print value)

Fennel even includes a ready-made repl which provides a few more creature comforts. rey triple kill meme with coroutines

[1] Before anyone rushes to "correct" this post: yes, I understand that recent redefinitions of the word "concurrent" broaden the term to include basically any form of multitasking. I find this redefinition to be perplexing and unhelpful and thus I'm using the term's original definition here; that is to say that two things are con-current if they are both simultaneously in the process of executing. Two posix threads on a multi-core system can both be currently executing at the same time, but two green threads or two coroutines in the same VM cannot, nor can two threads on a single-core system.

[2] I eventually replaced that with an actor-based system communicating across separate VM instances to give myself a bit more breathing room and allow scripts on that OS to run without affecting the frame rate, because in this case the OS could run arbitrary code of the user's creation.

« older | 2018-11-7T12:11:41