<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Nicolas Martyanoff – Brain dump</title>
    <description>Brain dump</description>
    <language>en-us</language>
    <managingEditor>nicolas@n16f.net (Nicolas Martyanoff)</managingEditor>
    <webMaster>nicolas@n16f.net (Nicolas Martyanoff)</webMaster>
    <link>https://www.n16f.net/tags/languages/index.xml</link>
    <atom:link href="https://www.n16f.net/tags/languages/index.xml" rel="self" type="application/rss+xml" />
    <lastBuildDate>Sun, 26 Jul 2026 00:00:00 +0000</lastBuildDate>

    
    <item xml:base="https://www.n16f.net/blog/concurrency-interactivity-mutability-choose-two/">
      <title>Concurrency, interactivity, mutability, choose two</title>
      <link>https://www.n16f.net/blog/concurrency-interactivity-mutability-choose-two/</link>
      <pubDate>Sun, 26 Jul 2026 18:00:00 +0000</pubDate>
      <guid isPermaLink="true">https://www.n16f.net/blog/concurrency-interactivity-mutability-choose-two/</guid>
      <author>nicolas@n16f.net (Nicolas Martyanoff)</author>

      <description>&lt;p&gt;You have a Common Lisp program running, multiple threads listening for network
connections, others processing data in the background. You were really careful
making sure that there are no data access conflicts. Concurrency, check. You use
Emacs and &lt;a href=&#34;https://slime.common-lisp.dev/&#34;&gt;SLIME&lt;/a&gt; to connect to your server,
inspect its state. Interactivity, check. You realize a global hash table
contains an incorrect value; no problem, just evaluate a simple
&lt;a href=&#34;https://www.lispworks.com/documentation/HyperSpec/Body/f_remhas.htm&#34;&gt;&lt;code&gt;REMHASH&lt;/code&gt;&lt;/a&gt;
expression. Mutability, check. Unfortunately another thread happens to read the
hash table while the form is being evaluated. Game over.&lt;/p&gt;
&lt;p&gt;You want concurrency, loosely defined as &amp;ldquo;having multiple execution threads
making progress in the same unit of time&amp;rdquo;, because it allows for faster
programs, processing more data faster. But now your programs are much more
complex because you need to protect data accesses to avoid deadlocks,
starvation, memory corruption and other unpleasant consequences.&lt;/p&gt;
&lt;p&gt;You want interactivity, because it is so convenient to be able to inspect and
update the state of your program at any time. But now you can access any data
whenever you want, data that may be read or written by concurrent threads.&lt;/p&gt;
&lt;p&gt;You want mutability, because it is practical.&lt;/p&gt;
&lt;p&gt;But you cannot have it all.&lt;/p&gt;
&lt;h2 id=&#34;dropping-interactivity&#34;&gt;Dropping interactivity&lt;/h2&gt;
&lt;p&gt;The most popular choice is to drop interactivity: since there is no one to
randomly access runtime data, there are no concurrency issues. C, Rust, Go, the
list of languages that go this way is long.&lt;/p&gt;
&lt;p&gt;You are efficient and safe, but you lose the ability to work with your systems
during execution. Frustrating during development, or to debug and fix complex
systems where &lt;a href=&#34;https://flownet.com/gat/jpl-lisp.html&#34;&gt;restarting is not always an
option&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;dropping-concurrency&#34;&gt;Dropping concurrency&lt;/h2&gt;
&lt;p&gt;You can still have multiple threads of course, but nothing in your program can
be read or written at the same time. Python and Ruby are good examples of
languages that drop concurrency by using a GIL (Global Interpreter Lock).&lt;/p&gt;
&lt;p&gt;You can execute multiple concurrent threads, but any access to Python or Ruby
data are protected by a global lock. You can run your program in a Python shell
or with &lt;a href=&#34;https://github.com/pry/pry&#34;&gt;Pry&lt;/a&gt; in Ruby, reading and writing data at
will in a safe way.&lt;/p&gt;
&lt;p&gt;Unfortunately it is slow. Most concurrent programs only require synchronization
for a tiny subset of all data accesses; tiny on purpose since synchronization is
slow. Locking all accesses has a very real cost that must be paid.&lt;/p&gt;
&lt;h2 id=&#34;dropping-mutability&#34;&gt;Dropping mutability&lt;/h2&gt;
&lt;p&gt;What if you could not really change data? Instead of reading the value of a
variable, you could have the runtime systematically (and safely) copy the value
and return it to you. Threads would communicate by, again, sending copies of
values. Of course you cannot go and directly modify any value anywhere; but
still the message-based approach means you can still safely update state at any
time by sending messages to threads.&lt;/p&gt;
&lt;p&gt;Erlang made this choice, and on paper it solves a lot of problems. You can run
threads (&amp;ldquo;processes&amp;rdquo; in Erlang) that operate concurrently safely since they
communicate with messages containing copied values instead of accessing shared
memory. And you can interact with the system at will.&lt;/p&gt;
&lt;p&gt;But again, there is no free lunch: copying data is slow. Very slow. Of course
you can optimize &lt;a href=&#34;https://en.wikipedia.org/wiki/Hash_array_mapped_trie&#34;&gt;data
representations&lt;/a&gt;, avoid
copying binary blobs (they are ref-counted in Erlang) because it would be
untenable. But it will still be &lt;a href=&#34;https://benchmarksgame-team.pages.debian.net/benchmarksgame/performance/knucleotide.html&#34;&gt;horribly
slow&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;you-cannot-have-it-all&#34;&gt;You cannot have it all&lt;/h2&gt;
&lt;p&gt;As usual choosing a language is choosing a set of trade-offs. Most
performance-sensitive programs drop interactivity so that they can limit shared
data accesses as much as possible. Developers wanting the convenience of
interactivity have to tolerate the extra cost of a global lock, or of an
immutable data model.&lt;/p&gt;
&lt;p&gt;Common Lisp developers will of course brag about how they can have it all, but
they will always have to keep in mind that anything they do in their REPL can
potentially break their program.&lt;/p&gt;
</description>

      
      <category>languages</category>
      
    </item>
    
  </channel>
</rss>
