#+TITLE: Event loops

An event loop is a frequently used pattern in concurrent programming:
event loops perhaps most famously used in Javascript -- and Node,
Android has a MessageQueue, along with most GUI implementations; and
of course, Python has Asyncio.

To paraphrase W. C. Williams, there are no ideas but in things so I'm
going to build an extremely simple one in Python as a demonstration.

The core of the idea is -- surprisingly enough -- a loop doing pieces
of work -- generally referred to as messages -- passed into
it. Messages are generally functions, or carefully delineated parts of
functions.

#+begin_src python :session loop :results output
def run_event_loop(queue):
    while queue:
        msg = queue.pop(0)
        msg()

run_event_loop([
    lambda: print("Hello"),
    lambda: print("World!")
])
#+end_src

#+RESULTS:
: Hello
: World!

That's cute, but not remarkably useful or better than just calling the
functions directly. As a first step, I'm going to introduce a little
bit of concurrency into the mix.

Consider two functions that I'd like to run simultaneously for reasons:
#+begin_src python :session conc :results output
def first():
    print("Function 1, part 1")
    print("Function 1, part 2")
    print("Function 1, part 3")

def second():
    print("Function 2, part 1")
    print("Function 2, part 2")
    print("Function 2, part 3")
#+end_src

#+RESULTS:




---

Before we dive deeply, I should remind you that concurrency allows
interleaving different units of work; parallelism means running different
units of work simultaneously. 

One of the biggest advantages of using an event loop that I've noticed
is being able to avoid all the messy synchronization you might
otherwise need: the loop and all the messages on it are in the same
thread. For your mental model: I'd recommend defining messages as
functions, or carefully delineated parts of functions.