<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Pl-Theory on CS Theorems</title><link>https://cs.lozic.me/areas/pl-theory/</link><description>Recent content in Pl-Theory on CS Theorems</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 22 Oct 2027 12:00:00 +0100</lastBuildDate><atom:link href="https://cs.lozic.me/areas/pl-theory/index.xml" rel="self" type="application/rss+xml"/><item><title>Abstract Interpretation and Galois Connections</title><link>https://cs.lozic.me/posts/t047-abstract-interpretation-and-galois-connections/</link><pubDate>Fri, 22 Oct 2027 12:00:00 +0100</pubDate><guid>https://cs.lozic.me/posts/t047-abstract-interpretation-and-galois-connections/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;
&lt;p&gt;Rice&amp;rsquo;s theorem (T011) told you every non-trivial semantic property is
undecidable. Your static analyzer must therefore be unsound, incomplete, or
non-terminating. In practice it is incomplete: it reports things that cannot
happen.&lt;/p&gt;</description></item><item><title>Parametricity: Theorems for Free</title><link>https://cs.lozic.me/posts/t045-parametricity-theorems-for-free/</link><pubDate>Fri, 15 Oct 2027 12:00:00 +0100</pubDate><guid>https://cs.lozic.me/posts/t045-parametricity-theorems-for-free/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;
&lt;p&gt;Someone hands you a function and no source:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-haskell" data-lang="haskell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;How much can you say about it? The instinct is nothing: any implementation is
possible, that is what polymorphism means.&lt;/p&gt;</description></item><item><title>Hindley–Milner and Principal Types</title><link>https://cs.lozic.me/posts/t043-hindley-milner-and-principal-types/</link><pubDate>Fri, 24 Sep 2027 12:00:00 +0100</pubDate><guid>https://cs.lozic.me/posts/t043-hindley-milner-and-principal-types/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;
&lt;p&gt;You write this in OCaml or Haskell and annotate nothing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ocaml" data-lang="ocaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;rec&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The compiler reports &lt;code&gt;('a -&amp;gt; 'b) -&amp;gt; 'a list -&amp;gt; 'b list&lt;/code&gt;. It found the most
general possible type, on its own, with no hints, and it will reject any call
that does not fit.&lt;/p&gt;</description></item><item><title>The Curry–Howard Correspondence</title><link>https://cs.lozic.me/posts/t042-the-curry-howard-correspondence/</link><pubDate>Fri, 17 Sep 2027 12:00:00 +0100</pubDate><guid>https://cs.lozic.me/posts/t042-the-curry-howard-correspondence/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;
&lt;p&gt;You write a function signature and it looks like a sentence:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-haskell" data-lang="haskell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Read it aloud: if $a$ implies $b$, and $b$ implies $c$, then $a$ implies $c$.
That is transitivity of implication, a rule of logic you have known since school.
And the implementation, &lt;code&gt;f g h = h . g&lt;/code&gt;, is the &lt;em&gt;proof&lt;/em&gt; of it: given evidence for
$a$, apply the first, then apply the second.&lt;/p&gt;</description></item><item><title>The Lambda Calculus and the Y Combinator</title><link>https://cs.lozic.me/posts/t041-the-lambda-calculus-and-the-y-combinator/</link><pubDate>Fri, 10 Sep 2027 12:00:00 +0100</pubDate><guid>https://cs.lozic.me/posts/t041-the-lambda-calculus-and-the-y-combinator/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;
&lt;p&gt;You are writing a language, or a configuration evaluator, or a template engine,
and you need recursion. So you add a &lt;code&gt;letrec&lt;/code&gt; form, and now the evaluator needs
to bind a name before the value it names exists. You reach for a mutable cell, a
placeholder that gets patched after construction, and something about it feels
like cheating.&lt;/p&gt;</description></item><item><title>The CALM Theorem and CRDTs</title><link>https://cs.lozic.me/posts/t067-the-calm-theorem-and-crdts/</link><pubDate>Fri, 03 Sep 2027 12:00:00 +0100</pubDate><guid>https://cs.lozic.me/posts/t067-the-calm-theorem-and-crdts/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;
&lt;p&gt;Every distributed result so far has been a prohibition. Two Generals: no
agreement over a lossy channel. FLP: no deterministic asynchronous consensus.
Byzantine: not below $3f+1$. CAP: not all three.&lt;/p&gt;</description></item><item><title>Rice's Theorem</title><link>https://cs.lozic.me/posts/t011-rices-theorem/</link><pubDate>Fri, 16 Oct 2026 12:00:00 +0200</pubDate><guid>https://cs.lozic.me/posts/t011-rices-theorem/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;
&lt;p&gt;The security team asks for a scanner with no false positives and no false
negatives. Every piece of malware caught, nothing legitimate quarantined.&lt;/p&gt;
&lt;p&gt;The platform team asks whether the analyzer can flag every function that
performs I/O, so the pure ones can be cached automatically.&lt;/p&gt;</description></item></channel></rss>