<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yusuke Endoh</title>
    <description>The latest articles on DEV Community by Yusuke Endoh (@mame).</description>
    <link>https://dev.to/mame</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F676879%2Fe8494d51-0e62-4b19-9fe7-5a1c42d831cc.png</url>
      <title>DEV Community: Yusuke Endoh</title>
      <link>https://dev.to/mame</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mame"/>
    <language>en</language>
    <item>
      <title>Quine Clique: 51 programs in 51 languages that all print each other</title>
      <dc:creator>Yusuke Endoh</dc:creator>
      <pubDate>Tue, 01 Sep 2026 18:53:02 +0000</pubDate>
      <link>https://dev.to/mame/quine-clique-51-programs-in-51-languages-that-all-print-each-other-39i0</link>
      <guid>https://dev.to/mame/quine-clique-51-programs-in-51-languages-that-all-print-each-other-39i0</guid>
      <description>&lt;p&gt;A quine is a program that prints itself. And a &lt;a href="https://en.wikipedia.org/wiki/Quine_%28computing%29#Multiquines" rel="noopener noreferrer"&gt;multiquine&lt;/a&gt; is a set of programs that print themselves and each other.&lt;/p&gt;

&lt;p&gt;I have created Quine Clique, which is a 51-language multiquine:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzne1odmh0ovvws2dccm3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzne1odmh0ovvws2dccm3.png" alt="Quine Clique" width="800" height="905"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Here is the video explanation:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/3f2wV7Odq8E" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;The repository is here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mame" rel="noopener noreferrer"&gt;
        mame
      &lt;/a&gt; / &lt;a href="https://github.com/mame/quine-clique" rel="noopener noreferrer"&gt;
        quine-clique
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      51 quines in 51 languages, every one able to print every other
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Quine Clique&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/mame/quine-clique/qc.rb" rel="noopener noreferrer"&gt;qc.rb&lt;/a&gt; is a quine written in Ruby: a program that prints itself
Ask it for Python, and it prints a Python quine instead
Or a JavaScript quine. Or a Rust quine. Or a C quine.
Or any of 50 languages in all.&lt;/p&gt;
&lt;p&gt;Every one of those quines can do the same: all of them can generate &lt;em&gt;each other&lt;/em&gt;.
A &lt;a href="https://en.wikipedia.org/wiki/Clique_(graph_theory)" rel="nofollow noopener noreferrer"&gt;clique&lt;/a&gt; of quines.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/mame/quine-clique/images/logo.png"&gt;&lt;img alt="Quine Clique" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fquine-clique%2FHEAD%2Fimages%2Flogo.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=3f2wV7Odq8E" rel="nofollow noopener noreferrer"&gt;▶ Video explanation (9 min)&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quine Clique 101&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Ruby Quine&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Here is &lt;code&gt;qc.rb&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/mame/quine-clique/images/thumbnail.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fquine-clique%2FHEAD%2Fimages%2Fthumbnail.png" alt="The text of qc.rb"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a Ruby program.
It is a quine.
Run it, and it prints itself.&lt;/p&gt;
&lt;div class="highlight highlight-text-shell-session notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;$ &lt;span class="pl-s1"&gt;ruby qc.rb &lt;span class="pl-k"&gt;&amp;gt;&lt;/span&gt; out.bin&lt;/span&gt;
$ &lt;span class="pl-s1"&gt;diff -s qc.rb out.bin&lt;/span&gt;
&lt;span class="pl-c1"&gt;Files qc.rb and out.bin are identical&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Ruby → Python&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Run &lt;code&gt;qc.rb&lt;/code&gt; with the argument &lt;code&gt;py&lt;/code&gt;, and it prints a quine written in Python.&lt;/p&gt;
&lt;div class="highlight highlight-text-shell-session notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;$ &lt;span class="pl-s1"&gt;ruby qc.rb py &lt;span class="pl-k"&gt;&amp;gt;&lt;/span&gt; qc.py&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Let's run it.&lt;/p&gt;
&lt;div class="highlight highlight-text-shell-session notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;$ &lt;span class="pl-s1"&gt;python3 qc.py &lt;span class="pl-k"&gt;&amp;gt;&lt;/span&gt; out.bin&lt;/span&gt;
$ &lt;span class="pl-s1"&gt;diff -s qc.py out.bin&lt;/span&gt;
&lt;span class="pl-c1"&gt;Files qc.py and&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mame/quine-clique" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Quine Clique?
&lt;/h2&gt;

&lt;p&gt;Let me walk you through it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Ruby quine: qc.rb
&lt;/h3&gt;

&lt;p&gt;First, this is qc.rb, which is the Ruby member of the Quine Clique.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx53tzhyt3d9xpenpyf72.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx53tzhyt3d9xpenpyf72.png" alt="qc.rb" width="760" height="705"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is a quine written in Ruby. That is, it prints itself when you run it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;The output of qc.rb is identical to qc.rb itself
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ruby qc.rb &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; out.bin
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;diff &lt;span class="nt"&gt;-s&lt;/span&gt; qc.rb out.bin
&lt;span class="go"&gt;Files qc.rb and out.bin are identical
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ruby → Python
&lt;/h3&gt;

&lt;p&gt;It is not just a quine. Run &lt;code&gt;ruby qc.rb py&lt;/code&gt;, and it prints a Python program, qc.py.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;qc.rb can print qc.py
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ruby qc.rb py &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; qc.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that Python program is a quine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;The output of qc.py is identical to qc.py itself
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python3 qc.py &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; out.bin
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;diff &lt;span class="nt"&gt;-s&lt;/span&gt; qc.py out.bin
&lt;span class="go"&gt;Files qc.py and out.bin are identical
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ruby ↔ Python
&lt;/h3&gt;

&lt;p&gt;Run &lt;code&gt;python3 qc.py rb&lt;/code&gt;, and it prints the original Ruby program, qc.rb.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;qc.py can print qc.rb
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python3 qc.py rb &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; out.bin
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;diff &lt;span class="nt"&gt;-s&lt;/span&gt; qc.rb out.bin
&lt;span class="go"&gt;Files qc.rb and out.bin are identical
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So qc.rb and qc.py are each a quine, and they can regenerate each other when you tell them which language you want.&lt;/p&gt;

&lt;p&gt;This is a multiquine of two languages, Ruby and Python.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F97u6tmybhd1s5op2xfjd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F97u6tmybhd1s5op2xfjd.png" alt="qc.rb and qc.py printing each other" width="799" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  + JavaScript
&lt;/h3&gt;

&lt;p&gt;That is not the end of it. JavaScript is supported too.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;ruby qc.rb js&lt;/code&gt;, and it prints a JavaScript quine, qc.js. Run &lt;code&gt;node qc.js&lt;/code&gt; and it prints itself; run &lt;code&gt;node qc.js rb&lt;/code&gt; and it prints the original qc.rb.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;qc.rb can print qc.js
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ruby qc.rb js &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; qc.js
&lt;span class="go"&gt;
&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;The output of qc.js is identical to qc.js itself
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;node qc.js &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; out.bin
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;diff &lt;span class="nt"&gt;-s&lt;/span&gt; qc.js out.bin
&lt;span class="go"&gt;Files qc.js and out.bin are identical
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And qc.js and qc.py can print each other as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;qc.js can print qc.py
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;node qc.js py &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; out.bin
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;diff &lt;span class="nt"&gt;-s&lt;/span&gt; qc.py out.bin
&lt;span class="go"&gt;Files qc.py and out.bin are identical

&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;qc.py can print qc.js
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python3 qc.py js &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; out.bin
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;diff &lt;span class="nt"&gt;-s&lt;/span&gt; qc.js out.bin
&lt;span class="go"&gt;Files qc.js and out.bin are identical
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpr7khj2u2cfzzkzlt3w5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpr7khj2u2cfzzkzlt3w5.png" alt="qc.rb, qc.py and qc.js printing one another" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  50 + 1 languages in total
&lt;/h3&gt;

&lt;p&gt;In the same way, it supports Rust, Go, TypeScript, C, C++, Objective-C, C#, Java, Kotlin, Swift, Zig, Lua, R, Perl, PHP, Haskell, OCaml, Standard ML, Scala, Haxe, Groovy, Clojure, Erlang, Elixir, F#, Racket, Scheme, Common Lisp, Prolog, D, Nim, Crystal, Vala, Pascal, Fortran, Forth, Octave, Tcl, AWK, Bash, CoffeeScript, Pike, and PostScript.&lt;/p&gt;

&lt;p&gt;Notably, it also supports five esoteric languages: &lt;a href="https://en.wikipedia.org/wiki/Brainfuck" rel="noopener noreferrer"&gt;brainfuck&lt;/a&gt;, &lt;a href="https://www.dangermouse.net/esoteric/piet.html" rel="noopener noreferrer"&gt;Piet&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Befunge" rel="noopener noreferrer"&gt;Befunge&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Whitespace_%28programming_language%29" rel="noopener noreferrer"&gt;Whitespace&lt;/a&gt;, and &lt;a href="https://en.wikipedia.org/wiki/Unlambda" rel="noopener noreferrer"&gt;Unlambda&lt;/a&gt;. Getting all of these to run at a realistic size and in a realistic time is quite something -- if you know, you know.&lt;/p&gt;

&lt;p&gt;The sizes and running times look like this.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Size: the smallest is qc.rb at 17 KB. The largest is Piet (qc.piet.gif) at 5.3 MB.&lt;/li&gt;
&lt;li&gt;Time: the slowest is Bash → Piet at about 7 minutes, followed by Piet → Piet at 4 minutes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyway, we now have a 50-language multiquine (51 if you count Ruby itself): programs that can all print one another. All 51 x 51 = 2,601 combinations are tested on GitHub Actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Let me explain how it is implemented. The key is QCLang, a minimal language made for Quine Clique.&lt;/p&gt;

&lt;h3&gt;
  
  
  QCLang in a nutshell
&lt;/h3&gt;

&lt;p&gt;It is a very simple language. Or maybe it is better to call it a VM. The only operation is subtraction, the only control structure is a loop, and the only storage is an accumulator and eight registers.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Instruction&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;!.../&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;print &lt;code&gt;...&lt;/code&gt; verbatim (&lt;code&gt;H&lt;/code&gt; is the escape; &lt;code&gt;Hx&lt;/code&gt; prints the character &lt;code&gt;x&lt;/code&gt; - 33)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;read one character from its own source into the accumulator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;(...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;loop while the accumulator is non-zero&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;print the accumulator as a character code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;0&lt;/code&gt;..&lt;code&gt;7&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;store the accumulator into a register&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;8&lt;/code&gt;..&lt;code&gt;?&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;load a register into the accumulator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;@&lt;/code&gt;..&lt;code&gt;G&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;subtract a register from the accumulator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;H&lt;/code&gt;..&lt;code&gt;~&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;set the accumulator to an immediate (the character code of the instruction)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;It is this simple so that an interpreter for QCLang can be written in a great many languages.&lt;/p&gt;

&lt;h3&gt;
  
  
  A quine in QCLang
&lt;/h3&gt;

&lt;p&gt;QCLang is specialized for writing quines, so a quine takes only these five characters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;amp;(*&amp;amp;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;&amp;amp;&lt;/code&gt; reads one byte of the source itself, and &lt;code&gt;(&lt;/code&gt;...&lt;code&gt;)&lt;/code&gt; loops. Inside the loop, &lt;code&gt;*&lt;/code&gt; prints the character that was read, and &lt;code&gt;&amp;amp;&lt;/code&gt; reads the next one. When &lt;code&gt;&amp;amp;&lt;/code&gt; reaches the end of the source, the accumulator becomes 0, the loop exits, and the program ends.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Ruby quine using QCLang
&lt;/h3&gt;

&lt;p&gt;If you prepare some Ruby code that runs QCLang, you can write a Ruby quine using QCLang.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;core&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'!core = HH/&amp;amp;(*&amp;amp;)!HH;run_qclang_in_ruby(core)/'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;run_qclang_in_ruby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;core&lt;/code&gt; contains QCLang code. And &lt;code&gt;run_qclang_in_ruby&lt;/code&gt; is a Ruby function that interprets QCLang (in reality its implementation has to be included too).&lt;/p&gt;

&lt;p&gt;The QCLang code in &lt;code&gt;core&lt;/code&gt; does the following.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;!core = HH/&lt;/code&gt; prints the string &lt;code&gt;core = '&lt;/code&gt; (&lt;code&gt;HH&lt;/code&gt; is the escaped form of &lt;code&gt;'&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;amp;(*&amp;amp;)&lt;/code&gt; is the QCLang quine, and prints the contents of &lt;code&gt;core&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;!HH;run_qclang_in_ruby(core)/&lt;/code&gt; prints the string &lt;code&gt;';run_qclang_in_ruby(core)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Concatenating these outputs gives back the code above. In other words, it is a Ruby quine.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Ruby/Python multiquine using QCLang
&lt;/h3&gt;

&lt;p&gt;Next is a Ruby and Python multiquine (the Ruby side of it). The QCLang part is pseudocode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;core&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'
  if "rb" is asked: !core = HH/&amp;amp;(*&amp;amp;)!HH;run_qclang_in_ruby(core)/
  if "py" is asked: !core = HH/&amp;amp;(*&amp;amp;)!HH;run_qclang_in_python(core)/
'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;run_qclang_in_ruby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;"rb"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks at the command-line argument, and prints the Ruby quine if &lt;code&gt;rb&lt;/code&gt; is given, or the Python quine if &lt;code&gt;py&lt;/code&gt; is given.&lt;/p&gt;

&lt;p&gt;The nice thing about this structure is that you can keep adding languages just by adding a branch to &lt;code&gt;core&lt;/code&gt;, like &lt;code&gt;if "js" is asked: !core = HH/&amp;amp;(*&amp;amp;)!HH;run_qclang_in_js(core)/&lt;/code&gt;. This means that when you add a language, you do not have to worry about its relationship with every existing language; you can add it modularly. Ideally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Constraints and tricks
&lt;/h3&gt;

&lt;p&gt;In practice there were all sorts of constraints: string literals are handled differently in each language, character codes are handled differently, some languages limit the source length, and so on. So you cannot add languages quite as cleanly and modularly as that. But writing all of this out would be endless, so I will skip it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side notes
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://en.wikipedia.org/wiki/Clique_%28graph_theory%29" rel="noopener noreferrer"&gt;clique&lt;/a&gt; in graph theory means a set of vertices that are all connected to each other. The programs in 50 + 1 languages can all reach each other, so it really is a clique.&lt;/p&gt;

&lt;p&gt;By the way, "clique" in English also has that slightly awkward meaning of an exclusive little group at school or at work, but there is no intent to shut out the languages that are not in here. Still, it is hard to add more languages to the Clique, so sorry to the ones that did not make it.&lt;/p&gt;

&lt;p&gt;The spider in the middle was drawn by &lt;a href="https://x.com/hirekoke" rel="noopener noreferrer"&gt;@hirekoke&lt;/a&gt;. The same person drew the ouroboros for Quine Relay. It is a spider because a clique diagram looks like a spider web.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related work
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/mame/quine-relay" rel="noopener noreferrer"&gt;Quine Relay&lt;/a&gt; (2013). A quine that goes through 128 languages in order and comes back to itself. It is a one-way chain of 128 languages, not a multiquine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/coolwanglu/quine-chameleon" rel="noopener noreferrer"&gt;Quine Chameleon&lt;/a&gt; (2015). A multiquine of 25 languages. It stays compact and elegant by restricting itself to languages with C-style string literals. Our advantage is that we also support brainfuck, Piet and others, which that approach can never cover.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mametter.hatenablog.com/entry/20161222/p1" rel="noopener noreferrer"&gt;Multiquine with ELVM&lt;/a&gt; (2016, in Japanese). A prototype multiquine built on &lt;a href="https://github.com/shinh/elvm" rel="noopener noreferrer"&gt;ELVM&lt;/a&gt;, a compiler infrastructure for esoteric languages. In principle it could produce a multiquine over many languages, but the code was far too big to run at a realistic size or in a realistic time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank you, AI
&lt;/h2&gt;

&lt;p&gt;As you can see from the conceptual prototype in &lt;a href="https://mametter.hatenablog.com/entry/20161222/p1" rel="noopener noreferrer"&gt;Multiquine with ELVM&lt;/a&gt;, the idea of Quine Clique had been with me since before 2016. But writing a QCLang interpreter in every language was too much of a chore, so it never happened.&lt;/p&gt;

&lt;p&gt;The reason it happened this time is, quite simply, AI coding agents. Tell them to write QCLang interpreters in 51 languages and they do so without complaint, and when the QCLang spec changes, they follow along. Though we did fight a lot over the beauty of the code. AI has no eye for beauty yet.&lt;/p&gt;

&lt;p&gt;I was a little worried that building a weird program with Claude Code might spoil the sense of accomplishment, but the moment it worked I still felt on top of the world, so all is well.&lt;/p&gt;

&lt;p&gt;By the way, what impressed me most about the AI was not the code it wrote but the explainer video it made. I handed it the README and a draft of this article as an outline, and it casually whipped up the video at the top of this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I introduced Quine Clique, a 51-language multiquine.&lt;/p&gt;

&lt;p&gt;Thanks to AI, a long-standing dream is now actually running, and I could not be happier. Go write your own fun quines with AI, everyone.&lt;/p&gt;

</description>
      <category>quine</category>
      <category>programming</category>
      <category>showdev</category>
      <category>ruby</category>
    </item>
    <item>
      <title>A Quine in Piet (and a plug for the esolang design contest)</title>
      <dc:creator>Yusuke Endoh</dc:creator>
      <pubDate>Fri, 31 Jul 2026 22:15:25 +0000</pubDate>
      <link>https://dev.to/mame/a-quine-in-piet-and-a-plug-for-the-esolang-design-contest-339o</link>
      <guid>https://dev.to/mame/a-quine-in-piet-and-a-plug-for-the-esolang-design-contest-339o</guid>
      <description>&lt;p&gt;I made a quine in &lt;a href="https://en.wikipedia.org/wiki/Esoteric_programming_language#Piet" rel="noopener noreferrer"&gt;Piet&lt;/a&gt;, an esoteric programming language.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Fquine.piet.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Fquine.piet.gif" alt="The Piet quine (2026 edition)" width="252" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Piet is an esolang that treats an image as a program: a cursor runs around the pixels of the image, and the changes in hue and lightness it crosses are the instructions it executes. See &lt;a href="https://www.dangermouse.net/esoteric/piet.html" rel="noopener noreferrer"&gt;the official page&lt;/a&gt; for the details.&lt;/p&gt;

&lt;p&gt;So this GIF file is a program, and running it prints this very GIF file.&lt;/p&gt;

&lt;h2&gt;
  
  
  The video
&lt;/h2&gt;

&lt;p&gt;Here is a video that visualizes the run: which cell is being executed, and how far the output has been printed.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/GwMtzhjCzyc"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  How to run it
&lt;/h2&gt;

&lt;p&gt;Feed the image to &lt;a href="https://www.bertnase.de/npiet/" rel="noopener noreferrer"&gt;npiet&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;npiet quine.piet.gif &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; out.bin
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;diff &lt;span class="nt"&gt;-s&lt;/span&gt; quine.piet.gif out.bin
&lt;span class="go"&gt;Files quine.piet.gif and out.bin are identical
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The image and the generator script live in &lt;a href="https://github.com/mame/piet-quine" rel="noopener noreferrer"&gt;this repository&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Structure
&lt;/h2&gt;

&lt;p&gt;Roughly speaking, the image splits into a "data part", which takes up most of the top, and a "code part" at the bottom.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Ffigs%2Fstructure.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Ffigs%2Fstructure.png" alt="The data part and the code part" width="800" height="612"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The data part
&lt;/h3&gt;

&lt;p&gt;The "data part" is an instruction sequence that runs in a vertical zigzag from the top left to the bottom right, pushing data as it goes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Ffigs%2Fdata.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Ffigs%2Fdata.png" alt="The data part: piling the data onto the stack" width="800" height="686"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that run is over, all the data needed is on the stack. The data is the pixels of the "code part", compressed with an adaptive run-length encoding.&lt;/p&gt;
&lt;h3&gt;
  
  
  The code part
&lt;/h3&gt;

&lt;p&gt;The run through the "code part" spirals clockwise.&lt;/p&gt;

&lt;p&gt;First it runs from the bottom right to the bottom left, emitting the GIF file header. The loop along the way computes the palette table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Ffigs%2Fcode-A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Ffigs%2Fcode-A.png" alt="Code part (1): emitting the GIF header and the palette table" width="800" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then it goes around a big loop at the top left. This one looks at the data on the stack and emits the pixels of the "data part" area.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Ffigs%2Fcode-B.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Ffigs%2Fcode-B.png" alt="Code part (2): drawing the data part" width="800" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next it goes around a big loop at the top right. This one likewise looks at the data on the stack and emits the pixels of the "code part" area.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Ffigs%2Fcode-C.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Ffigs%2Fcode-C.png" alt="Code part (3): drawing the code part" width="800" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally it emits the trailing data of the GIF file and stops. The dot of "Y. Endoh" is the terminator that halts the execution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Ffigs%2Fcode-D.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmame%2Fpiet-quine%2FHEAD%2Ffigs%2Fcode-D.png" alt="Code part (4): emitting the end of the GIF file and halting" width="800" height="214"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Restoring the 2009 edition
&lt;/h2&gt;

&lt;p&gt;I originally made a Piet quine back in 2009. Here is the article from back then (in Japanese):&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://mametter.hatenablog.com/entry/20091006/p1" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.image.st-hatena.com%2Fimage%2Fscale%2F84e9573a65ffe601e7183bcd9cc9c52951209170%2Fbackend%3Dimagemagick%3Bversion%3D1%3Bwidth%3D1300%2Fhttp%253A%252F%252Fdame.dyndns.org%252Fmisc%252Fpiet%252Fquine.gif" height="400" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://mametter.hatenablog.com/entry/20091006/p1" rel="noopener noreferrer" class="c-link"&gt;
             Piet Quine - まめめも
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            npiet 1.0b には出力部分にバグがあったので動きませんでしたが、パッチ書いて報告したら直してもらえました。npiet 1.1 ならこのように。 $ ./npiet-1.1/npiet quine.gif &amp;gt; quine2.gif $ diff quine.gif quine2.gif
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmametter.hatenablog.com%2Ficon%2Ffavicon" width="48" height="48"&gt;
          mametter.hatenablog.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;But the image file itself had gone missing, for various reasons (and of course the generator script with it). So remaking the Piet quine stayed on my mind and I attempted it several times, but the motivation barrier to redoing a quine I had already made was pretty high, and Piet's sheer painfulness won every time.&lt;/p&gt;

&lt;p&gt;Then it hit me: surely a modern AI coding agent can bring it back! The result was that I burned through my weekly limit on Claude Code's Fable and got nowhere. It even started lying to me: "Final conclusion: this is impossible in principle."&lt;/p&gt;

&lt;p&gt;While telling it "that can't be right, I actually made one", I remembered that I had once given &lt;a href="https://speakerdeck.com/mame/quine-and-obfuscated-programming" rel="noopener noreferrer"&gt;a talk about the Piet quine&lt;/a&gt;, and pointed it at that. Claude Code then restored the Piet quine of that era from the image in that PDF and got it running again. Ah, so that was the way in.&lt;/p&gt;

&lt;p&gt;Here is what came back.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhf00u7qq5hhxqotduwev.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhf00u7qq5hhxqotduwev.gif" alt="The Piet quine (2009 edition)" width="22" height="1864"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Very long.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the 2026 edition
&lt;/h2&gt;

&lt;p&gt;Once something was running again, analyzing it and reconstructing the Ruby script that generates it was easy work for Claude Code.&lt;/p&gt;

&lt;p&gt;By the way, I had always thought the 2009 Piet quine was too tall to look good, so I had Claude Code build a landscape one.&lt;/p&gt;

&lt;p&gt;That turned out to be surprisingly hard.&lt;br&gt;
The first step was refactoring: I had it design a DSL for laying out Piet and restructure the generator around it. The DSLs it came up with were genuinely bad, but after a lot of back and forth we got there.&lt;/p&gt;

&lt;p&gt;Next came the folded data part. Claude Code could not build this on its own at all, and did not understand it even when I designed it and gave instructions; this took the longest to get working.&lt;/p&gt;

&lt;p&gt;This is what we ended up with at that point.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhzkggs0yhi6ajosipiri.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhzkggs0yhi6ajosipiri.gif" alt="The first working 2026 edition (400 x 295)" width="400" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is pointlessly huge and ugly, so the next job was shrinking it, which means golfing -- and Claude Code's golfing skills were just as bad. When I coached it with something like "you can cut instructions if you compute it in this order", it called me a genius, which did wonders for my self-esteem.&lt;/p&gt;

&lt;p&gt;One thing led to another, and we got it down to my target of a 4:3 landscape image (252 x 189 pixels), so I am calling it done for now. 16:9 is still a way off.&lt;/p&gt;
&lt;h2&gt;
  
  
  Thoughts on Piet and AI coding agents
&lt;/h2&gt;

&lt;p&gt;As of 2026, it seems fair to say that AI coding agents cannot draw Piet properly on their own.&lt;/p&gt;

&lt;p&gt;That said, it is also a fact that this rewrite would not have happened without Claude Code. Anyone who has drawn Piet will know that it is not a maintainable language. Change one number -- the height of the image, say -- and it collides with the rest of the code and breaks, so you end up re-laying pixels by hand. That was exactly the wall that had kept me from redoing the Piet quine, and Claude Code does that tedious work without complaining, which was unambiguously great.&lt;/p&gt;

&lt;p&gt;Anyway, it was fun to touch Piet again after all these years. It really is designed with an exquisite balance.&lt;/p&gt;
&lt;h2&gt;
  
  
  A plug for the esolang design contest
&lt;/h2&gt;

&lt;p&gt;If this article made you curious about esolangs, I have something to tell you.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://yhara.github.io/nandoku/" rel="noopener noreferrer"&gt;"2026 Obfuscated Programming Language Design Contest"&lt;/a&gt; is running right now.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://yhara.github.io/nandoku/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;yhara.github.io&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Design an esoteric programming language and submit it. I am one of the judges too. I am waiting for the most fun esolangs you can come up with.&lt;/p&gt;

&lt;p&gt;The deadline is October 1, two months from now. Please do!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Which Programming Language Is Best for Claude Code?</title>
      <dc:creator>Yusuke Endoh</dc:creator>
      <pubDate>Thu, 05 Mar 2026 01:09:13 +0000</pubDate>
      <link>https://dev.to/mame/which-programming-language-is-best-for-claude-code-508a</link>
      <guid>https://dev.to/mame/which-programming-language-is-best-for-claude-code-508a</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;I had Claude Code implement a very simplified version of Git in 13 languages. Ruby, Python, and JavaScript were the fastest, cheapest, and most stable. Statically typed languages were 1.4–2.6× slower and more expensive.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fno4u5gnjx8v5v7yrj2d0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fno4u5gnjx8v5v7yrj2d0.png" alt="Cost v1+v2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Which programming language is best suited for AI coding agents?&lt;/p&gt;

&lt;p&gt;"Static typing prevents AI hallucination bugs!"&lt;br&gt;
"No, skipping type annotations saves tokens!"&lt;/p&gt;

&lt;p&gt;There's plenty of qualitative debate, but quantitative data is scarce. So I ran an experiment.&lt;/p&gt;
&lt;h2&gt;
  
  
  Experiment
&lt;/h2&gt;

&lt;p&gt;I asked &lt;a href="https://docs.anthropic.com/en/docs/claude-code" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt; to implement a "mini-git" — a simplified version of Git — in various languages, and measured the time and cost for each. Git was famously built by Linus in two weeks, so it seemed like a good task.&lt;/p&gt;

&lt;p&gt;The task was split into two phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;v1 (New project)&lt;/strong&gt;: Implement &lt;code&gt;init&lt;/code&gt;, &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;commit&lt;/code&gt;, and &lt;code&gt;log&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v2 (Feature extension)&lt;/strong&gt;: Add &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;diff&lt;/code&gt;, &lt;code&gt;checkout&lt;/code&gt;, and &lt;code&gt;reset&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The prompt was simply: "Read &lt;a href="https://github.com/mame/ai-coding-lang-bench/blob/main/SPEC-v1.txt" rel="noopener noreferrer"&gt;SPEC-v1.txt&lt;/a&gt;, implement it, and make sure &lt;a href="https://github.com/mame/ai-coding-lang-bench/blob/main/test-v1.sh" rel="noopener noreferrer"&gt;test-v1.sh&lt;/a&gt; passes." v2 was analogous.&lt;/p&gt;

&lt;p&gt;The languages compared:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Languages&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dynamic&lt;/td&gt;
&lt;td&gt;Python, Ruby, JavaScript, Perl, Lua&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynamic + type checker&lt;/td&gt;
&lt;td&gt;Python/mypy, Ruby/Steep&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Static&lt;/td&gt;
&lt;td&gt;TypeScript, Go, Rust, C, Java&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Functional&lt;/td&gt;
&lt;td&gt;Scheme (dynamic), OCaml (static), Haskell (static)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Python/mypy writes fully type-annotated Python verified with &lt;code&gt;mypy --strict&lt;/code&gt;. Ruby/Steep writes RBS type signatures verified with &lt;code&gt;steep check&lt;/code&gt;. These allow direct comparison of type-checking overhead within the same language.&lt;/p&gt;

&lt;p&gt;Each language was run 20 times. The model was Claude Opus 4.6 (high effort).&lt;/p&gt;
&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;Average results across 20 trials, sorted by average cost.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;Tests passed (v1+v2)&lt;/th&gt;
&lt;th&gt;Time (v1+v2)&lt;/th&gt;
&lt;th&gt;Avg. cost&lt;/th&gt;
&lt;th&gt;LOC (v2)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ruby&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;73.1s ± 4.2s&lt;/td&gt;
&lt;td&gt;$0.36&lt;/td&gt;
&lt;td&gt;219&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;74.6s ± 4.5s&lt;/td&gt;
&lt;td&gt;$0.38&lt;/td&gt;
&lt;td&gt;235&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;81.1s ± 5.0s&lt;/td&gt;
&lt;td&gt;$0.39&lt;/td&gt;
&lt;td&gt;248&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;101.6s ± 37.0s&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;324&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;115.4s ± 34.4s&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;303&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;38/40&lt;/td&gt;
&lt;td&gt;113.7s ± 54.8s&lt;/td&gt;
&lt;td&gt;$0.54&lt;/td&gt;
&lt;td&gt;303&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Perl&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;130.2s ± 44.2s&lt;/td&gt;
&lt;td&gt;$0.55&lt;/td&gt;
&lt;td&gt;315&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python/mypy&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;125.3s ± 19.0s&lt;/td&gt;
&lt;td&gt;$0.57&lt;/td&gt;
&lt;td&gt;326&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OCaml&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;128.1s ± 28.9s&lt;/td&gt;
&lt;td&gt;$0.58&lt;/td&gt;
&lt;td&gt;216&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lua&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;143.6s ± 43.0s&lt;/td&gt;
&lt;td&gt;$0.58&lt;/td&gt;
&lt;td&gt;398&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scheme&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;130.6s ± 39.9s&lt;/td&gt;
&lt;td&gt;$0.60&lt;/td&gt;
&lt;td&gt;310&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;133.0s ± 29.4s&lt;/td&gt;
&lt;td&gt;$0.62&lt;/td&gt;
&lt;td&gt;310&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;155.8s ± 40.9s&lt;/td&gt;
&lt;td&gt;$0.74&lt;/td&gt;
&lt;td&gt;517&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Haskell&lt;/td&gt;
&lt;td&gt;39/40&lt;/td&gt;
&lt;td&gt;174.0s ± 44.2s&lt;/td&gt;
&lt;td&gt;$0.74&lt;/td&gt;
&lt;td&gt;224&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ruby/Steep&lt;/td&gt;
&lt;td&gt;40/40&lt;/td&gt;
&lt;td&gt;186.6s ± 69.7s&lt;/td&gt;
&lt;td&gt;$0.84&lt;/td&gt;
&lt;td&gt;304&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Out of 600 runs (15 languages × 2 phases × 20 trials), only 3 failed (tests did not pass). The failures were Rust (2) and Haskell (1). In one of the Rust failure logs, the agent claimed "the tests are wrong." Since all other Rust trials succeeded, this appears to be a hallucination.&lt;/p&gt;
&lt;h3&gt;
  
  
  Total Time and Cost
&lt;/h3&gt;

&lt;p&gt;Dot plots of total time (v1 + v2):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fylcn7y7i7mmn9wxgkwpc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fylcn7y7i7mmn9wxgkwpc.png" alt="Total time"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And cost:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fno4u5gnjx8v5v7yrj2d0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fno4u5gnjx8v5v7yrj2d0.png" alt="Total cost"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ruby, Python, and JavaScript are the top 3: 73–81 seconds, $0.36–0.39, with low standard deviations — fast and stable.&lt;/p&gt;

&lt;p&gt;From 4th place onward (Go, Rust, Java), variance increases sharply. Go averages 102s but with ±37s of spread.&lt;/p&gt;

&lt;p&gt;Time and cost are strongly correlated:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61fvfvref0xxiouze6s9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61fvfvref0xxiouze6s9.png" alt="Time vs Cost"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Lines of Code
&lt;/h3&gt;

&lt;p&gt;LOC after v2 completion:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feql1t05arln421gfffg8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feql1t05arln421gfffg8.png" alt="Lines of code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OCaml (216), Ruby (219), and Haskell (224) are the most compact. C stands out at 517 lines.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7v1elh1hel7iggt0wrf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7v1elh1hel7iggt0wrf.png" alt="Time vs LOC"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interestingly, fewer LOC does not imply faster or cheaper generation. OCaml and Haskell are compact but mid-to-low in speed and cost efficiency.&lt;/p&gt;
&lt;h3&gt;
  
  
  v1/v2 Detailed Results
&lt;/h3&gt;

&lt;p&gt;Breakdown by phase:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;v1 Time&lt;/th&gt;
&lt;th&gt;v1 Turns&lt;/th&gt;
&lt;th&gt;v1 LOC&lt;/th&gt;
&lt;th&gt;v1 Tests&lt;/th&gt;
&lt;th&gt;v2 Time&lt;/th&gt;
&lt;th&gt;v2 Turns&lt;/th&gt;
&lt;th&gt;v2 LOC&lt;/th&gt;
&lt;th&gt;v2 Tests&lt;/th&gt;
&lt;th&gt;Total Time&lt;/th&gt;
&lt;th&gt;Avg. Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ruby&lt;/td&gt;
&lt;td&gt;33.2s± 2.5s&lt;/td&gt;
&lt;td&gt;6.0&lt;/td&gt;
&lt;td&gt;107&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;40.0s± 3.0s&lt;/td&gt;
&lt;td&gt;7.0&lt;/td&gt;
&lt;td&gt;219&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;73.1s± 4.2s&lt;/td&gt;
&lt;td&gt;$0.36&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;32.9s± 1.3s&lt;/td&gt;
&lt;td&gt;6.0&lt;/td&gt;
&lt;td&gt;113&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;41.8s± 4.5s&lt;/td&gt;
&lt;td&gt;7.1&lt;/td&gt;
&lt;td&gt;235&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;74.6s± 4.5s&lt;/td&gt;
&lt;td&gt;$0.38&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript&lt;/td&gt;
&lt;td&gt;36.0s± 3.5s&lt;/td&gt;
&lt;td&gt;6.0&lt;/td&gt;
&lt;td&gt;123&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;45.1s± 4.1s&lt;/td&gt;
&lt;td&gt;7.2&lt;/td&gt;
&lt;td&gt;248&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;81.1s± 5.0s&lt;/td&gt;
&lt;td&gt;$0.39&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;47.5s±34.5s&lt;/td&gt;
&lt;td&gt;7.7&lt;/td&gt;
&lt;td&gt;143&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;54.1s±12.3s&lt;/td&gt;
&lt;td&gt;9.7&lt;/td&gt;
&lt;td&gt;324&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;101.6s±37.0s&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;td&gt;64.3s±31.1s&lt;/td&gt;
&lt;td&gt;8.7&lt;/td&gt;
&lt;td&gt;152&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;51.2s± 8.1s&lt;/td&gt;
&lt;td&gt;9.6&lt;/td&gt;
&lt;td&gt;303&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;115.4s±34.4s&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;53.6s±36.7s&lt;/td&gt;
&lt;td&gt;9.4&lt;/td&gt;
&lt;td&gt;139&lt;/td&gt;
&lt;td&gt;19/20&lt;/td&gt;
&lt;td&gt;60.1s±19.2s&lt;/td&gt;
&lt;td&gt;10.1&lt;/td&gt;
&lt;td&gt;303&lt;/td&gt;
&lt;td&gt;19/20&lt;/td&gt;
&lt;td&gt;113.7s±54.8s&lt;/td&gt;
&lt;td&gt;$0.54&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Perl&lt;/td&gt;
&lt;td&gt;84.4s±43.1s&lt;/td&gt;
&lt;td&gt;9.2&lt;/td&gt;
&lt;td&gt;173&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;45.7s± 6.8s&lt;/td&gt;
&lt;td&gt;7.5&lt;/td&gt;
&lt;td&gt;315&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;130.2s±44.2s&lt;/td&gt;
&lt;td&gt;$0.55&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python/mypy&lt;/td&gt;
&lt;td&gt;52.7s± 8.3s&lt;/td&gt;
&lt;td&gt;9.2&lt;/td&gt;
&lt;td&gt;171&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;72.6s±14.4s&lt;/td&gt;
&lt;td&gt;12.2&lt;/td&gt;
&lt;td&gt;326&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;125.3s±19.0s&lt;/td&gt;
&lt;td&gt;$0.57&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OCaml&lt;/td&gt;
&lt;td&gt;80.9s±28.8s&lt;/td&gt;
&lt;td&gt;11.2&lt;/td&gt;
&lt;td&gt;111&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;47.1s± 6.0s&lt;/td&gt;
&lt;td&gt;9.2&lt;/td&gt;
&lt;td&gt;216&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;128.1s±28.9s&lt;/td&gt;
&lt;td&gt;$0.58&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lua&lt;/td&gt;
&lt;td&gt;96.4s±42.8s&lt;/td&gt;
&lt;td&gt;10.1&lt;/td&gt;
&lt;td&gt;226&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;47.2s± 5.2s&lt;/td&gt;
&lt;td&gt;8.1&lt;/td&gt;
&lt;td&gt;398&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;143.6s±43.0s&lt;/td&gt;
&lt;td&gt;$0.58&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scheme&lt;/td&gt;
&lt;td&gt;66.7s±36.7s&lt;/td&gt;
&lt;td&gt;8.9&lt;/td&gt;
&lt;td&gt;171&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;63.9s±10.0s&lt;/td&gt;
&lt;td&gt;10.6&lt;/td&gt;
&lt;td&gt;310&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;130.6s±39.9s&lt;/td&gt;
&lt;td&gt;$0.60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;td&gt;69.9s±18.8s&lt;/td&gt;
&lt;td&gt;12.2&lt;/td&gt;
&lt;td&gt;149&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;63.1s±17.8s&lt;/td&gt;
&lt;td&gt;11.3&lt;/td&gt;
&lt;td&gt;310&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;133.0s±29.4s&lt;/td&gt;
&lt;td&gt;$0.62&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;65.0s±18.2s&lt;/td&gt;
&lt;td&gt;8.2&lt;/td&gt;
&lt;td&gt;276&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;90.8s±39.1s&lt;/td&gt;
&lt;td&gt;13.7&lt;/td&gt;
&lt;td&gt;517&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;155.8s±40.9s&lt;/td&gt;
&lt;td&gt;$0.74&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Haskell&lt;/td&gt;
&lt;td&gt;74.3s±39.1s&lt;/td&gt;
&lt;td&gt;10.3&lt;/td&gt;
&lt;td&gt;119&lt;/td&gt;
&lt;td&gt;19/20&lt;/td&gt;
&lt;td&gt;99.6s±32.4s&lt;/td&gt;
&lt;td&gt;16.4&lt;/td&gt;
&lt;td&gt;224&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;174.0s±44.2s&lt;/td&gt;
&lt;td&gt;$0.74&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ruby/Steep&lt;/td&gt;
&lt;td&gt;105.0s±65.2s&lt;/td&gt;
&lt;td&gt;20.2&lt;/td&gt;
&lt;td&gt;150&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;81.6s± 8.8s&lt;/td&gt;
&lt;td&gt;17.2&lt;/td&gt;
&lt;td&gt;304&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;186.6s±69.7s&lt;/td&gt;
&lt;td&gt;$0.84&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;"Turns" is the number of API round-trips (tool call → result → next response) within a single prompt execution.&lt;/p&gt;
&lt;h3&gt;
  
  
  v1 (New Project) Time
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ikzqiiphr4yhbjwxdm0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ikzqiiphr4yhbjwxdm0.png" alt="v1 time"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;v1 shows the largest gap between languages. Python (32.9s) and Ruby (33.2s) lead, followed by JavaScript (36.0s). Ruby/Steep takes 105.0s — 3.2× slower than plain Ruby. Lua (96.4s) and OCaml (80.9s) are also slow.&lt;/p&gt;

&lt;p&gt;v1 starts from an empty directory, so languages requiring project config files (&lt;code&gt;Cargo.toml&lt;/code&gt;, &lt;code&gt;package.json&lt;/code&gt;, etc.) incur additional overhead. Python, Ruby, and JavaScript only need to generate a single &lt;code&gt;minigit&lt;/code&gt; file, which may partly explain the gap.&lt;/p&gt;
&lt;h3&gt;
  
  
  v2 (Feature Extension) Time
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6btbkmwuwn0vkum5bgn3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6btbkmwuwn0vkum5bgn3.png" alt="v2 time"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In v2, the gap narrows. The top 3 remain Ruby (40.0s), Python (41.8s), JavaScript (45.1s). Perl (45.7s), OCaml (47.1s), and Lua (47.2s) follow closely.&lt;/p&gt;

&lt;p&gt;Haskell is the slowest in v2 as well, averaging 99.6s despite having the fewest LOC (224) — it appears to spend heavily on thinking tokens. C takes 90.8s, weighed down by its high LOC (517).&lt;/p&gt;

&lt;p&gt;Type-checker overhead: Python/mypy is 1.6–1.7× slower than Python; Ruby/Steep is 2.0–3.2× slower than Ruby.&lt;/p&gt;
&lt;h2&gt;
  
  
  Data and Reproduction
&lt;/h2&gt;

&lt;p&gt;All experiment code and results are available on GitHub:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mame" rel="noopener noreferrer"&gt;
        mame
      &lt;/a&gt; / &lt;a href="https://github.com/mame/ai-coding-lang-bench" rel="noopener noreferrer"&gt;
        ai-coding-lang-bench
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Which programming language is best for AI coding agents? Benchmarking 13 languages with Claude Code.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Which Programming Language Is Best for AI Coding Agents?&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A quantitative benchmark comparing how efficiently &lt;a href="https://docs.anthropic.com/en/docs/claude-code" rel="nofollow noopener noreferrer"&gt;Claude Code&lt;/a&gt; generates code across 13 programming languages.&lt;/p&gt;
&lt;p&gt;For a detailed discussion, see the blog post: &lt;a href="https://dev.to/mame/which-programming-language-is-best-for-claude-code-508a" rel="nofollow"&gt;Which Programming Language Is Best for Claude Code?&lt;/a&gt; / &lt;a href="https://zenn.dev/mametter/articles/3e8580ec034201" rel="nofollow noopener noreferrer"&gt;日本語版&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;TL;DR&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;At least for prototyping-scale tasks, Ruby, Python, and JavaScript (not TypeScript) appear to be the best fit for Claude Code — fastest, cheapest, and most stable.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Motivation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;"Static typing prevents AI hallucination bugs!" vs. "Dynamic typing saves tokens!" — qualitative arguments abound, but quantitative data is scarce. This experiment aims to fill that gap.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Experiment&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;We asked Claude Code (Opus 4.6) to implement a &lt;strong&gt;mini-git&lt;/strong&gt; — a simplified version of Git — in various programming languages, and measured the time, cost, and lines of code for each.&lt;/p&gt;
&lt;p&gt;The task is split into two phases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;v1 (New project)&lt;/strong&gt;: Implement &lt;code&gt;init&lt;/code&gt;, &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;commit&lt;/code&gt;, and &lt;code&gt;log&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mame/ai-coding-lang-bench" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Per-run results are in &lt;a href="https://github.com/mame/ai-coding-lang-bench/blob/main/results/report.md" rel="noopener noreferrer"&gt;report.md&lt;/a&gt;. Execution logs and generated source code are on the &lt;a href="https://github.com/mame/ai-coding-lang-bench/tree/data" rel="noopener noreferrer"&gt;data branch&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note: benchmark.rb uses &lt;code&gt;--dangerously-skip-permissions&lt;/code&gt;, so if you want to reproduce the experiment, please be careful (I ran it inside Docker).&lt;/p&gt;

&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;What follows is my interpretation. I'm a Ruby committer, so please keep that bias in mind. I also haven't analyzed all the generated code in detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  What causes the speed/cost differences?
&lt;/h3&gt;

&lt;p&gt;This experiment can't pinpoint a single cause, and I don't think there is one. But we can form hypotheses from the trends:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type system&lt;/strong&gt;: Dynamic languages are consistently faster and more stable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conciseness&lt;/strong&gt;: Shorter code generally means faster generation — but OCaml and Haskell are compact yet expensive, apparently due to high thinking-token usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Procedural vs. functional&lt;/strong&gt;: Excluding the top 3, there isn't a large gap between procedural and functional languages. Notably, OCaml achieved 47.1s in v2, rivaling JavaScript (though OCaml can be written in a procedural style, so a pure functional comparison is difficult).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language-specific difficulty&lt;/strong&gt;: C's memory management and Rust's ownership model may add overhead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI familiarity&lt;/strong&gt;: Python, Ruby, and JavaScript have vastly more training data. Scheme and Haskell likely have less, and the results reflect this. Ruby/Steep's larger overhead (2.0–3.2×) vs. Python/mypy (1.6–1.7×) may also reflect lower AI familiarity with Steep compared to mypy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most likely, these factors combine to produce the observed results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Doesn't lack of types mean more bugs?
&lt;/h3&gt;

&lt;p&gt;Possibly. The tests pass, but untested paths in dynamically typed languages may have type errors.&lt;/p&gt;

&lt;p&gt;That said, type errors are among the easiest bugs to detect and fix. If an agent frequently introduced type errors without a type checker, it would likely introduce logic bugs at a similar rate — at which point the problem goes beyond type checking.&lt;/p&gt;

&lt;p&gt;It's also worth noting that the only 3 failures out of 600 runs were in Rust (2) and Haskell (1) — both statically typed languages with unique concepts like ownership and monads. This may be coincidence, but types don't prevent all bugs.&lt;/p&gt;

&lt;h3&gt;
  
  
  A 2× difference isn't that big, is it?
&lt;/h3&gt;

&lt;p&gt;I think it is.&lt;/p&gt;

&lt;p&gt;In real-world development, you're constantly iterating: prompt → wait → think about the next task → prompt again. The difference between waiting 30 seconds and 60 seconds matters — not just in total time, but in focus and flow. Response time is critical in iterative development.&lt;/p&gt;

&lt;p&gt;"Take longer to build something robust" is a reasonable argument, but when competitors are shipping at twice the speed, is waiting the right call? Development speed is itself a dimension of quality.&lt;/p&gt;

&lt;p&gt;That said, if the difference shrinks to 1 second vs. 0.5 seconds in the future, then it truly won't matter.&lt;/p&gt;

&lt;h3&gt;
  
  
  The task is too small. Static typing should shine at larger scales.
&lt;/h3&gt;

&lt;p&gt;I don't disagree. But designing a large-scale benchmark that's fair across 15 languages is quite challenging. Someone should try it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Isn't ecosystem and runtime performance more important for language choice?
&lt;/h3&gt;

&lt;p&gt;Absolutely. From a generation standpoint too — if you can leverage an ecosystem, there's less code to generate, which should be faster and cheaper. And if runtime speed is essential for your application, there's no reason to choose a slow dynamic language.&lt;/p&gt;

&lt;p&gt;For this experiment, I intentionally chose a task with no external library dependencies to isolate language-level differences. The spec uses a custom hash instead of SHA-256 for this reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I quantitatively evaluated which programming languages are best suited for code generation with Claude Code. At least for prototyping-scale tasks, Ruby, Python, and JavaScript appear to be the best fit.&lt;/p&gt;

&lt;p&gt;Static typing may become advantageous at larger scales — someone should test this.&lt;/p&gt;

&lt;p&gt;The classic strategy — start with a dynamic language, then migrate to a static one as the project matures — may still be the right call. Coding agents seem very capable at cross-language migration (needs verification), making this an increasingly realistic option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Evaluated in March 2026. Given the pace of AI progress, results may look different in a few months.&lt;/li&gt;
&lt;li&gt;This experiment was supported by &lt;a href="https://claude.com/contact-sales/claude-for-oss" rel="noopener noreferrer"&gt;the Claude for Open Source Program&lt;/a&gt;. Thanks Anthropic for 6 months of free Claude Max 20x!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
