summaryrefslogtreecommitdiff
path: root/posts/guile-cooperative-repl.md
diff options
context:
space:
mode:
Diffstat (limited to 'posts/guile-cooperative-repl.md')
-rw-r--r--posts/guile-cooperative-repl.md73
1 files changed, 0 insertions, 73 deletions
diff --git a/posts/guile-cooperative-repl.md b/posts/guile-cooperative-repl.md
deleted file mode 100644
index 50cf39e..0000000
--- a/posts/guile-cooperative-repl.md
+++ /dev/null
@@ -1,73 +0,0 @@
-title: A Cooperative REPL Server for Guile 2.0.10
-date: 2014-01-24 22:00
-tags: gnu, scheme, guile, wsu
-summary: Guile 2.0.10 will include a new type of REPL server suited for single-threaded applications.
----
-
-The next release of GNU Guile, 2.0.10, is to be released “real soon
-now”. My contribution to this release is the new `(system repl
-coop-server)` module. This module introduces a useful variant of the
-REPL server that I’ve named the “cooperative” REPL server. It is
-cooperative because it can be integrated with single-threaded programs
-without the thread synchronization issues present in the ordinary REPL
-server.
-
-Using delimited continuations and mvars (another new feature coming in
-Guile 2.0.10), it was possible to create a REPL server whose clients
-all ran in the context of a single thread. The cooperative server
-puts the user in control of when it is safe to evaluate expressions
-entered at the REPL prompt.
-
-Here’s an example of how to use it:
-
-```scheme
-(use-modules (system repl coop-server))
-
-(define server (spawn-coop-repl-server))
-
-(while #t
- (poll-coop-repl-server server)
- (sleep 1))
-```
-
-That’s all it takes. There are only 2 public procedures!
-`spawn-coop-repl-server` creates a new cooperative REPL server
-object and starts listening for clients. `poll-coop-repl-server`
-applies pending operations for the server.
-
-Now that I’ve explained the API, onto the implementation details!
-Although the REPLs run in the context of a single thread, there are
-other threads needed to make it all work. To avoid thinking too much
-about thread synchronization issues, I used the new `(ice-9 mvars)`
-module to provide thread-safe objects for read/write operations. I
-used delimited continuations in order to yield control back to the
-user from inside the loop.
-
-When the server is spawned, a new thread is created to listen for
-client connections. When a client connects, a request to create a new
-REPL is put into the server’s "evaluation" mvar, the storage place for
-pending server operations. The job of `poll-coop-repl-server` is to
-attempt to take from the evaluation mvar and execute the operation
-stored within, if any. In this case, an operation called `new-repl`
-is hanging out along with the client socket. The contents of the mvar
-are removed, and a new REPL is started in the main thread.
-
-This new REPL is run within a "prompt", Guile’s implementation of
-delimited continuations. The prompt allows the REPL to be paused
-temporarily while waiting for user input. Just before the prompt is
-aborted, a thunk containing the logic to read user input is stored
-within the client’s "read" mvar for yet another thread to use.
-Without this additional thread and the use of a prompt, the main
-thread would block while waiting for input, defeating the purpose of
-the cooperative REPL. The reader thread waits for this thunk to
-appear in the read mvar. When it appears, the thunk is applied and
-the resulting expression is stored as an `eval` operation within the
-evaluation mvar. When `poll-coop-repl-server` is called, the REPL
-prompt is resumed. The input expression is evaluated in the context
-of the main thread, the result is printed, and the process repeats
-itself.
-
-That’s all, folks. Thanks for following along. I’m very excited to
-use the cooperative REPL server in guile-2d and I hope that others
-find it useful as well. Many thanks to Mark Weaver for helping me out
-when I got stuck and for all of the helpful code review.